8

I need to remove redundant (String) elements from a list. Or perhaps to prevent them from being entered in the first place is the better solution? Sets do not allow duplicates, but they also do not keep order and I need the order. This is a common problem for me so I am looking for a possible language solution for full efficiency.

(In the past I have extended an Array Class to add my own add_unique() method, but this seems like it is a common enough issue to be handled by the language and likely more efficiently.)

Thanks,

_g

george koller
  • 3,721
  • 6
  • 23
  • 27

4 Answers4

3

Array object DART, test in https://dartpad.dev/4d3a724429bbd605f4682b7da253a16e

void main() {
      var duplicates = [
        {"b": 1},
        {"b": 2},
        {"b": 1},
        {"b": 2}
      ];
    
      var resArr = [];
      duplicates.forEach((item) {
        var i = resArr.indexWhere((x) => x["b"] == item["b"]);
        if (i <= -1) {
          resArr.add({"b": item["b"]});
        }
      });
      print(resArr);
    }
Julian Ramos
  • 596
  • 6
  • 3
2

You need a LinkedSet to contain only uniques and keep insertion order, but currently we don't have it in dart. However you can emulate a LinkedSet using a LinkedHashMap:

var input = ["apple", "orange", "cherries", "pears", "apple", "apple", "orange"];
var uniques = new LinkedHashMap<String, bool>();
for (var s in input) {
  uniques[s] = true;
}
for (var key in uniques.getKeys()) {
  print ("$key");
}
mdakin
  • 1,310
  • 11
  • 17
  • Thanks, I will keep the LinkedHashMap in mind. The need for keeping an ordered set of unique elements happens again and again in my work, this gets down to the basics of the problem. Good to know. – george koller Oct 16 '12 at 23:30
  • 1
    I created an issue for LinkedSets: http://code.google.com/p/dart/issues/detail?id=5976 – mdakin Oct 18 '12 at 12:16
  • 2
    There is now a LinkedHashSet implementation in dart. – mdakin Sep 02 '13 at 15:12
0

Today this must be done manually. Dart does not offer a set which keeps insertion order. Note that the Dart container library is going to be revamped. Please visit www.dartbug.com and add this feature request. To do this manually, you could:

1) call indexOf before adding. 2) Maintain a Set and a List. The Set can be used to keep things unique while the List maintains order.

I would recommend 1.

John

Cutch
  • 3,511
  • 1
  • 18
  • 12
0

You could use the list as you do and as cutch mentioned manually add your own method to verify duplicates and sorting similar to the below.

import 'dart:html';

var someList = new List<String>();
String newItem = '';

void main() {
  newItem = 'item 3';  
  if(!itemExistsInList(someList, newItem)){
    someList.add(newItem);
    sortList(someList);
  }

  // expected item 3
  print(someList);

  newItem = 'item 1';
  if(!itemExistsInList(someList, newItem)){
    someList.add(newItem);
    sortList(someList);
  }

// expected item 1, item 3
  print(someList);

  newItem = 'item 3';
  if(!itemExistsInList(someList, newItem)){
    someList.add(newItem);
    sortList(someList);
  }

// expected item 1, item 3. Same as previous as secondary item 3 was not added
  print(someList);
}

// returns true if the specified item already exists in the specified list
// otherwise false
bool itemExistsInList(List<String> list, String item){
  return list.some((v) => v.indexOf(item) != -1);
}

// sorts the list
void sortList(List<String> list){
  list.sort((a, b) => a.compareTo(b));
}

You don't need to call the sortList() function every time you add, I only did this for demonstration. Only calling it when you actually need to is enough off course.

.sort(), .some() and .indexOf are explained in more detail under the collections section of the DART library documentation

Nope
  • 22,147
  • 7
  • 47
  • 72
  • @georgekoller: Has this helped you in any way or are you having still issues with this? – Nope Oct 16 '12 at 12:25
  • Dart is still in Alpha and I have hesitated to start extending classes as it looks like many of the issues are being addressed almost daily. Your suggestion to use (v.indexOf(item) != -1) is what I have used and it seems to be working as expected and it should be efficient. Thanks again! – george koller Oct 16 '12 at 12:44