Muhammad Ali Khan
Muhammad Ali Khan

Reputation: 171

Searching key in Dart map if key is a list

I'm solving a problem which is on a website "exercism.io" of Dart.Link to problem statement I'm using map as a data structure and key data type is List. The problem arises when I try to access the map, I'm confused how to search the list for that key.

I tried asking on different platforms like slacks but got no help. Also, I tried to search a similar problem but unfortunately since Dart is a new language there is not much out there.

int score(String str) {
  int score;
  //Map declaration and definition 
  Map<List<String>, int> scrabbleDat = {
    //list as a key and int as a value
    ['A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T']: 1,
    ['D', 'G']: 2,
    ['B', 'C', 'M', 'P']: 3,
    ['F', 'H', 'V', 'W', 'Y']: 4,
    ['K']: 5,
    ['J', 'X']: 8,
    ['Q', 'Z']: 10
  };
  for (int i = 0; i < str.length; ++i) {
    //Trying to access map based on the str parameter
    //Adding the value returned to score variable
    score += scrabbleDat[str[i]];
  }
  return score; // returning the score
}

The code is running flawlessly but the output obtained is null for any string.

Upvotes: 1

Views: 892

Answers (1)

lrn
lrn

Reputation: 71623

What you want is a map where multiple keys map to the same value.

Using lists of values as keys does not let you look up efficiently. You can search linearly through the keys, and then through the individual lists, until you find the key you are looking for, but you are not using the map as a Map.

I'd build the map so that it has each key mapped to its value directly:

Map<String, int> map = {};
void _addAll(List<String> keys, int value) { 
  for (var key in keys) map[key] = value;
}
_addAll(['A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'], 1);
_addAll(['D', 'G'], 2);
_addAll(['B', 'C', 'M', 'P'], 3);
_addAll(['F', 'H', 'V', 'W', 'Y'], 4);
_addAll(['K'], 5);  // or just: map['K'] = 5;
_addAll(['J', 'X'], 8);
_addAll(['Q', 'Z'], 10);

It's not that much easier than simply writing the map literal:

var map = {
  'A': 1, 'B': 3, 'C': 3, 'D': 2, 'E': 1, 'F': 4, 'G': 2, 'H': 4,
  'I': 1, 'J': 8, 'K': 5, 'L': 1, 'M': 3, 'N': 1, 'O': 1, 'P': 3,
  'Q': 10, 'R': 1, 'S': 1, 'T': 1, 'U': 1, 'V': 4, 'W': 4, ,X': 8,
  'Y': 4, 'Z': 10
};

After this, your map is initialized, and you can look up each letter directly:

print(map['X']);  // prints 8.

Another option, since your keys have consequtive ASCII values, is to make an index based table, and calculate the index from the letter's ASCII value:

//           A B C D E F G H I J K L M N O P Q  R S T U V W X Y Z
var table = [1,3,3,2,1,4,2,4,1,8,5,1,3,1,1,3,10,1,1,1,1,4,4,8,4,10];
int lookup(String letter) => table[letter.codeUnitAt(0) - 0x41 /*A*/];

Upvotes: 2

Related Questions