Suppose I have a List<map> that looks like this:

‘Books’:[
    ‘B1’{
        ‘id’: ’1234’,
        ‘bookName’: ’book1’
    },
    ‘B2’{
        ‘id’: ’4567’,
        ‘bookName’: ’book2’
    },
    ‘B3’{
        ‘id’: ’1234’,
        ‘bookName’: ’book3’
    },
    ‘B4’{
        ‘id’: ’8912’,
        ‘bookName’: ’book4’
    },

    …
];

I’m trying to return the entire book without duplications in Id.

The expected result should be like this:

‘B1’{
        ‘id’: ’1234’,
        ‘bookName’: ’book1’
    },
‘B2’{
        ‘id’: ’4567’,
        ‘bookName’: ’book2’
    },
‘B4’{
        ‘id’: ’8912’,
        ‘bookName’: ’book4’
    },


Solution 1: Christopher Moore

I guessed what your input map was and made a solution based on this answer from Basic Coder.

final list = {
 'Books':[
    {
        'id':'1234',
        'bookName':'book1'
    },
    {
        'id':'4567',
        'bookName':'book2'
    },
    {
        'id': '1234',
        'bookName':'book3'
    },
    {
        'id': '8912',
        'bookName':'book4'
    },
]};

void main() {
  print('With duplicates $list');

  final ids = list['Books']!.map<String>((e) => e['id']!).toSet();
  list['Books']!.retainWhere((Map x) {
    return ids.remove(x['id']);
  });

  print('Without duplicates $list');
}

This code shows your input as the variable list, which seems to be what you were going for with your provided data. The code then obtains a list of each id of the book and removes duplicates by changing it to a Set. Then it only retains elements in the original list with those non-duplicate ids.

Remove the ! operators if you're not using null-safety.


Solution 2: Randal Schwartz

Here's one inspired by Christopher's answer:

void main() {
  var books = {
    'B1': {
      'id': '1234',
      'bookName': 'book1',
    },
    'B2': {
      'id': '4567',
      'bookName': 'book2',
    },
    'B3': {'id': '1234', 'bookName': 'book3'},
    'B4': {'id': '8912', 'bookName': 'book4'},
  };

  var seen = <String>{};

  var kept = books.entries.where((me) => seen.add(me.value['id'] ?? 'OTHER'));

  print(Map.fromEntries(kept));
}

I think it's a bit simpler, since it doesn't have to populate the Set first. I also learned that Set.add returns a bool to indicate the element didn't exist before. Nice.