0

I Use this sample for search in Map but not work :|:

  var xmenList = ['4','xmen','4xmen','test'];
  var xmenObj = {
  'first': '4',
  'second': 'xmen',
  'fifth': '4xmen',
   'author': 'test'
  };

  print(xmenList.indexOf('4xmen')); // 2
  print(xmenObj.indexOf('4xmen')); // ?

but I have error TypeError: xmenObj.indexOf$1 is not a function on last code line.

Pelease help me to search in map object simple way same as indexOf.

A1Gard
  • 4,070
  • 4
  • 31
  • 55

3 Answers3

1

I found the answer:

 print(xmenObj.values.toList().indexOf('4xmen')); // 2

or this:

  var ind = xmenObj.values.toList().indexOf('4xmen') ;
  print(xmenObj.keys.toList()[ind]); // fifth
A1Gard
  • 4,070
  • 4
  • 31
  • 55
  • You can't assume that the order of the keys and values is the same. In your 2nd example if `xmenObj.keys.toList()[ind]` returns the correct key, it will only be by luck. – Günter Zöchbauer Jun 05 '18 at 02:51
  • @GünterZöchbauer Luck? are you kidding me ? but this answer right for my work :) – A1Gard Jun 05 '18 at 21:41
  • yes, pure luck. You base your solution on an assumption that is not guaranteed to be true. – Günter Zöchbauer Jun 06 '18 at 03:45
  • Actually, the Dart `HashMap` and `LinkedHashMap` do promise that iterating values is equivalent to iterating keys and looking up the corresponding value. As long as the map *doesn't change* between iterations, we also promise that the iteration order is stable. That's only something we can guarantee for platform library maps, obviously, but it's recommended in general. – lrn Jun 08 '18 at 08:28
0

Maps are not indexable by integers, so there is no operation corresponding to indexOf. If you see lists as specialized maps where the keys are always consecutive integers, then the corresponding operation should find the key for a given value. Maps are not built for that, so iterating through all the keys and values is the only way to get that result. I'd do that as:

K keyForValue<K, V>(Map<K, V> map, V value) {
  for (var entry in map.entries) {
    if (entry.value == value) return key;
  }
  return null;
}

The entries getter is introduced in Dart 2. If you don't have that, then using the map.values.toList().indexOf(value) to get the iteration position, and then map.keys.elementAt(thatIndex) to get the corresponding key.

If you really only want the numerical index, then you can skip that last step. It's not amazingly efficient (you allocate a new list and copy all the values). Another approach is:

int indexOfValue<V>(Map<Object, V> map, V value) {
  int i = 0;
  for (var mapValue in map.values) {
    if (mapValue == value) return i;
    i++;
  }
  return -1;
}
lrn
  • 64,680
  • 7
  • 105
  • 121
0

You can search using .where(...) if you want to find all that match or firstWhere if you assume there can only be one or you only want the first

var found = xmenObj.keys.firstWhere(
    (k) => xmenObj[k] == '4xmen', orElse: () => null);
print(xmenObj[found]);
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567