Get most popular value in a list

Viewed 1801

How I can get the most popular number from a list in dart without using any third party libraries?

var list = [0, 1, 1, 2, 2, 2, 3, 3, 4]; // most popular number is 2

If there are two or more popular numbers then the output should be a List with both values. Example:

One popular number:

var list = [0, 1, 1, 2, 2, 2, 3, 3, 4];
// Output should be [2]

Two or more popular numbers:

var list = [0, 1, 1, 2, 2, 2, 3, 3, 3];
// Output should be [2, 3]

Thank you in advance for your help!

5 Answers

try this to count each element in list:

var list = [0, 1, 1, 2, 2, 2, 3, 3, 4];
  var popular = Map();

  list.forEach((l) {
    if(!popular.containsKey(l)) {
      popular[l] = 1;
    } else {
      popular[l] +=1;
    }
  });

This works...you can optimize it

  var list = [1, 1, 2, 2, 3, 4, 5];
  list.sort();
  var popularNumbers = [];
  List<Map<dynamic, dynamic>> data = [];
  var maxOccurrence = 0;

  var i = 0;
  while (i < list.length) {
    var number = list[i];
    var occurrence = 1;
    for (int j = 0; j < list.length; j++) {
      if (j == i) {
        continue;
      }
      else if (number == list[j]) {
        occurrence++;
      }
    }
    list.removeWhere((it) => it == number);
    data.add({number: occurrence});
    if (maxOccurrence < occurrence) {
      maxOccurrence = occurrence;
    }
  }

  data.forEach((map) {
    if (map[map.keys.toList()[0]] == maxOccurrence) {
      popularNumbers.add(map.keys.toList()[0]);
    }
  });

  print(popularNumbers);

I guess I found the solution.

Let me explain it to you:

I had queried through your list and checked whether the keys of the map contains the element or not. If the map does not contain the element as the key then, it will create a key from the element and pass 1 as the value. If the map does contain the element as a key then it will simply increment the value.

Once the map is ready, I had sorted the map values and stored them in a List. From the sorted map values I had taken the last element from the list of sorted values because we had sorted it in ascending order so the most popular value will be at last.

At last, I had queried through the map and check whether the value of the particular key is equal to the popularValue or not. If it is then we are adding the current key and value to the mostPopularValues list.

If I got something wrong please let me know.

 void main() {
  List list = [0, 1, 1, 1, 2, 2, 2, 3, 3, 4];

  List mostPopularValues = [];

  var map = Map();

  list.forEach((element) {
    if (!map.containsKey(element)) {
      map[element] = 1;
    } else {
      map[element] += 1;
    }
  });

  print(map);
  // o/p : {0: 1, 1: 3, 2: 3, 3: 2, 4: 1}

  List sortedValues = map.values.toList()..sort();

  print(sortedValues);
  // o/p : [1, 1, 2, 3, 3]

  int popularValue = sortedValues.last;

  print(popularValue);
  // o/p : 3

  map.forEach((k, v) {
    if (v == popularValue) {
      mostPopularValues.add("$k occurs $v time in the list");
    }
  });

  print(mostPopularValues);
  // o/p : [1 occurs 3 time in the list, 2 occurs 3 time in the list]
}

Not sure if that's the best solution, but it works pretty well. Let me know if there are any doubts.

    final list = [0, 1, 1, 2, 2, 2, 3, 3, 4];

    // Count occurrences of each item
    final folded = list.fold({}, (acc, curr) {
      acc[curr] = (acc[curr] ?? 0) + 1;
      return acc;
    }) as Map<dynamic, dynamic>;

    // Sort the keys (your values) by its occurrences
    final sortedKeys = folded.keys
        .toList()
        ..sort((a, b) => folded[b].compareTo(folded[a]));

    print('Most popular value: ${sortedKeys.first}'); // 1
    print('Second most popular value: ${sortedKeys[1]}'); // 2

I have solved this problem by defining an extension on Iterable:

extension MostPopularItemsExtension<E> on Iterable<E> {
  /// Returns the most popular items, where all items in the returned
  /// list have the same number of occurances. If [this] is empty, returns an
  /// empty list
  ///
  /// Examples:
  ///   `[1,2,3,2].mostPopularItems() == [2]`
  ///   `[1,1,2,2].mostPopularItems() == [1,2]`
  Iterable<E> mostPopularItems() {
    if (isEmpty) return [];
    final itemsCounted = <E, int>{};
    for (final e in this) {
      if (itemsCounted.containsKey(e)) {
        itemsCounted[e] = itemsCounted[e]! + 1;
      } else {
        itemsCounted[e] = 1;
      }
    }
    final highestCount = (itemsCounted.values.toList()..sort()).last;
    return itemsCounted.entries
        .where((e) => e.value == highestCount)
        .map((e) => e.key);
  }
}

The basic idea is to count all occurrences of each item in a Map object, get the highest count from this map and then return all items that have that specific number of occurrences.

Related