Dart: How to update value in Set

Viewed 4880

How do I update the value at index 0

Set<int> set = {1, 2, 3};
set[0] = 0; // error

Note:

I am not looking for workaround like convert Set to List, add element and further convert it back to Set

3 Answers

Sets elements only have indices incidentally because they are iterables. You can't "update the value at position x" because any update may change the order.

I assume you do want to keep the iteration order (and in that case, you really should be using a list!), so the following won't work:

 void update<T>(Set<T> elements, int index, T newValue) {
   set.remove(set.elementAt(index));
   set.add(newValue);
 }

The problem here is that you won't preserve iteration order, the new value that you added is likely at the end of the iteration (if you are using an insertion-ordered set), or maybe the order has changed completely (if you are not).

An approach which works for insertion-ordered sets:

void replace<T>(Set<T> set, int index, T newValue) {
  if (set.contains(newValue)) throw StateError("New value already in set");
  int counter = 0;
  while (counter < set.length) {
    var element = set.first;
    set.remove(element);
    if (counter == index) element = newValue;
    set.add(element);
    counter++;
  }
}

This repeatedly removes the first element in the set, then inserts it again, except for the indexth element, where it inserts newValue instead. This only works for insertion-ordered sets (like the default LinkedHashSet). (Notice that this will not work if newValue is already in the set, so I made it throw in that case).

For all other sets, there is no better solution that (set.toList()..[index] = newValue).toSet().

You can not change values in a set directly with index, but you can do it with map.

Set<int> set = {1, 2, 3};
Set<int> updated = set.map((item) => item == 1 ? 0 : item).toSet();

print(updated); // => {0, 2, 3}

You cannot change the value in a set but you could get a similar result by converting it to a list and changing it back to set.

Set<int> set = {1,2,3};
List<int> list = set.toList();
list[1] = 12;
var newset = list.toSet();

this may be a quick solution to your problem.

Related