Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dart, a nice way of replacing keys and values in maps?

I have a Map and I want to go through both the values and keys and replace any occurrences of particular objects which meet some set criteria with some other objects, so if I find a key that meets a specific criteria.
I want to swap that key for a different object that still points at the same value object in the map, similarly if I find a value that I want to replace I want the original key to point at the replacement value.
Here is some code that works for a simplified example but it looks quite ugly, is there a nicer way of achieving this, meaning a method which doesn't require that you extract every key and value you want to replace and then write the replacements back in.
It would be nicer to be able to just iterate of the map once rather than iterating over the keys, and then iterating over all the keys and values to be replaced?

void main(){
  //replace all values of instance A with an Object and all keys starting with "t" with the same key minus the "t"
  var m = {
    "one": new A(),
    "two": new A(),
    "three": new B(),
    "four": new B()
  };
  mapKeyAndValueSwapper(m,
    keyMeetsCondition: (k) => k.startsWith("t"),
    valueMeetsCondition: (v) => v is A,
    keyReplacer: (k) => k.replaceFirst("t", ""),
    valueReplacer: (v) => new Object());
  print(m);
}

mapKeyAndValueSwapper(Map m, {bool keyMeetsCondition(key), bool valueMeetsCondition(value), dynamic keyReplacer(key), dynamic valueReplacer(value)}){
  var keysToReplace = [];
  var keysToReplaceValuesFor = [];
  var keys = m.keys;
  keys.forEach((k){
    if(keyMeetsCondition != null){
      if(keyMeetsCondition(k)){
        keysToReplace.add(k);
      }
    }
    if(valueMeetsCondition != null){
      if(valueMeetsCondition(m[k])){
        keysToReplaceValuesFor.add(k);
      }
    }
  });
  keysToReplaceValuesFor.forEach((k){
    m[k] = valueReplacer(m[k]);
  });
  keysToReplace.forEach((k){
    m[keyReplacer(k)] = m.remove(k);
  });
}

class A{}
class B{}
like image 235
Daniel Robinson Avatar asked Oct 17 '25 10:10

Daniel Robinson


1 Answers

I think this does the same:

  Map newMap = {};
  m.forEach((k, v) {
    var key = k;
    var value = v;
    if(m[k] is A) {
      value = new Object();
    }
    if(k.startsWith('t')) {
      key = k.replaceFirst('t', '');
    }
    newMap[key]=value;
  });
like image 161
Günter Zöchbauer Avatar answered Oct 19 '25 12:10

Günter Zöchbauer