0

I have a list of strings, when I click a button I want to generate a new list with a specific number of items from my original list of strings.

I'm able to generate a random list with no repeating items but the number of items that returns is random. For example I want a new list of 5 items, sometimes it returns with 2 items other times 4 etc.

var randomList = new List.generate(
            5, (_) => originalList[Random().nextInt(originalList.length)]).toSet().toList();

I've found lots of info for returning 1 random item, but nothing about multiples.

EDIT:

Thank you everyone for the responses, I was able to fix my problem by using shuffle like so

var randomList = (originalList..shuffle()).take(5).toList();

2 Answers 2

2

Your method of getting random items out of the original list will result in duplicates, which are then eliminated when you call .toSet(), which is why you get lists of varying lengths.

Instead of calling .toSet() to prevent duplicates, we need to be sure that no duplicates are chosen in the first place.

One way of doing that would be to generate a list of numbers from 0 up to originalList.length - 1, then shuffle them, and then choose the first n numbers from that list, and map them to values from original list.

void main() {
  List<String> originalList = ["hello", "what", "goodbye", "Test", "Apple", "Banana"];

  List<int> indices = List<int>.generate(originalList.length, (i) => i);

  indices.shuffle();

  int newCount = 3;

  List<String> randomList = indices.take(newCount).map((i) => originalList[i]).toList();

  print(randomList);
}

This method is efficient, and has a worst case performance of O(n), assuming dart has an efficient shuffle() implementation (which I'm sure it does).

Sign up to request clarification or add additional context in comments.

Comments

1

The problem here is the list generates duplicates nonetheless.

var randomList = new List.generate(5, (_) => originalList[Random().nextInt(originalList.length)])

The list could contain [dello, kello, hello, gello, hello] (for example, assume items are taken from the original list)

Now performing .toSet() on this will remove the duplicate hello from the list, this is what causes the list size to be random. In this instance it's two duplicates, but later on it could have more.

A simple solution for this would be

var randomList = [];

List.generate(5, (_) {
   var randomString = originalList[Random().nextInt(originalList.length)];

   while (randomList.contains(randomString)) {
      randomString = originalList[Random().nextInt(originalList.length)];
   }

   randomList.add(randomString);
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.