deepSortByValue method

Map<K, V> deepSortByValue()

Returns new instance of Map, which is recursively sorted by values. It sorts by values nested List, Set or Map (primitive collections), nested primitive collections inside nested primitive collections and so on.

it gets rid of incomparable values like:

If there are more List, Set or Map, it groups them, sorts by length and puts in the following order:

  1. int and double values
  2. String values
  3. All List sorted by length
  4. All Set sorted by length
  5. All Map sorted by length

Implementation

Map<K, V> deepSortByValue() {
  var intAndDoubleValues = Map<dynamic, dynamic>.fromEntries(entries
      .where((element) => element.value is int || element.value is double));

  var sortedKeysFromIntAndDoubleValues = intAndDoubleValues.keys.toList(
      growable: false)
    ..sort((a, b) => intAndDoubleValues[a].compareTo(intAndDoubleValues[b]));
  var sortedIntAndDoubleValues = LinkedHashMap.fromIterable(
      sortedKeysFromIntAndDoubleValues,
      key: (k) => k,
      value: (k) => intAndDoubleValues[k]);

  var stringValues = Map<dynamic, dynamic>.fromEntries(
      entries.where((element) => element.value is String));
  var sortedKeysFromStringValues = stringValues.keys.toList(growable: false)
    ..sort((a, b) => stringValues[a].compareTo(stringValues[b]));
  var sortedStringValues = LinkedHashMap.fromIterable(
      sortedKeysFromStringValues,
      key: (k) => k,
      value: (k) => stringValues[k]);

  var listValues = Map<dynamic, dynamic>.fromEntries(
      entries.where((element) => element.value is List));
  listValues.forEach((key, value) {
    listValues[key] = (value as List).deepSort();
  });
  var sortedKeysFromListValues = listValues.keys.toList(growable: false)
    ..sort((a, b) =>
        (listValues[a] as List).length < (listValues[b] as List).length
            ? -1
            : 1);
  var sortedListValues = LinkedHashMap.fromIterable(sortedKeysFromListValues,
      key: (k) => k, value: (k) => listValues[k]);

  var setValues = Map<dynamic, dynamic>.fromEntries(
      entries.where((element) => element.value is Set));
  setValues.forEach((key, value) {
    setValues[key] = (value as Set).deepSort();
  });
  var sortedKeysFromSetValues = setValues.keys.toList(growable: false)
    ..sort((a, b) =>
        (setValues[a] as Set).length < (setValues[b] as Set).length ? -1 : 1);
  var sortedSetValues = LinkedHashMap.fromIterable(sortedKeysFromSetValues,
      key: (k) => k, value: (k) => setValues[k]);

  var mapValues = Map<dynamic, dynamic>.fromEntries(
      entries.where((element) => element.value is Map));
  mapValues.forEach((key, value) {
    mapValues[key] = (value as Map).deepSortByValue();
  });
  var sortedKeysFromMapValues = mapValues.keys.toList(growable: false)
    ..sort((a, b) =>
        (mapValues[a] as Map).length < (mapValues[b] as Map).length ? -1 : 1);
  var sortedMapValues = LinkedHashMap.fromIterable(sortedKeysFromMapValues,
      key: (k) => k, value: (k) => mapValues[k]);

  return <K, V>{
    ...sortedIntAndDoubleValues.cast<K, V>(),
    ...sortedStringValues.cast<K, V>(),
    ...sortedListValues.cast<K, V>(),
    ...sortedSetValues.cast<K, V>(),
    ...sortedMapValues.cast<K, V>(),
  };
}