Home > Blockchain >  Fetch random items from list without duplicate or repetition - Dart
Fetch random items from list without duplicate or repetition - Dart

Time:05-29

I'm trying to fetch the randomly specific number of items from one list and add them to the other list but without duplication.

For example: pick three random items from the list randomly and put them into another list. This is what I have achieved so far but this could pick the duplicate item again.

List itemList = ['NAME1', 'NAME2', 'NAME3', 'NAME4', 'NAME3', 'NAME5', 'NAME2'];

List randomItems = [];


for(var i=0; i<=2; i  ){ // run the loop for three times
  int randomNumber = Random().nextInt(itemList.length); //generate random number within itemList range
  randomItems.add(itemList[randomNumber]); // duplication occur, for example: NAME2 could be added two times
}

CodePudding user response:

There are several steps we can do to solve this problem. First, we want to get rid of the duplicate elements in the list. We can here do that by converting the list to a Set:

  List<String> itemList = [
    'NAME1',
    'NAME2',
    'NAME3',
    'NAME4',
    'NAME3',
    'NAME5',
    'NAME2'
  ];
  Set<String> itemSet = itemList.toSet();
  print(itemSet); // {NAME1, NAME2, NAME3, NAME4, NAME5}

Then, we want to extract 3 random elements from this new Set in such a way that we can't select the same element twice. The easiest way to solve this is by shuffle the elements randomly and then take elements from our collection. But Set does not have the concept of any specific "order" and we can't therefore shuffle our Set.

So let's convert our Set back to a List:

  Set<String> itemSet = itemList.toSet();
  List<String> itemListFromSet = itemSet.toList();
  print(itemListFromSet); // [NAME1, NAME2, NAME3, NAME4, NAME5]

We can then shuffle this new list:

  itemListFromSet.shuffle();
  print(itemListFromSet); // [NAME3, NAME2, NAME4, NAME5, NAME1]

If we then want 3 random selected elements, we can just take 3 elements from this randomly ordered list. So e.g. (take returns an iterable which we then makes a new list of):

List<String> randomItems = itemListFromSet.take(3).toList();

A complete solution would look like:

void main() {
  List<String> itemList = [
    'NAME1',
    'NAME2',
    'NAME3',
    'NAME4',
    'NAME3',
    'NAME5',
    'NAME2'
  ];
  Set<String> itemSet = itemList.toSet();
  List<String> itemListFromSet = itemSet.toList();

  itemListFromSet.shuffle();

  List<String> randomItems = itemListFromSet.take(3).toList();

  print(randomItems); // [NAME5, NAME2, NAME4]
}

Which can be reduced down to:

void main() {
  List<String> itemList = [
    'NAME1',
    'NAME2',
    'NAME3',
    'NAME4',
    'NAME3',
    'NAME5',
    'NAME2'
  ];
  List<String> randomItems =
      (itemList.toSet().toList()..shuffle()).take(3).toList();

  print(randomItems); // [NAME3, NAME4, NAME2]
}
  •  Tags:  
  • dart
  • Related