Como verificar se existe chave ou valor no mapa?

87

Tenho um scala Map e gostaria de testar se um determinado valor existe no mapa.

myMap.exists( /*What should go here*/ )
Nabegh
fonte

Respostas:

141

Existem várias opções diferentes, dependendo do que você quer dizer.

Se você quer dizer par de valores-chave "valor" , pode usar algo como

myMap.exists(_ == ("fish",3))
myMap.exists(_ == "fish" -> 3)

Se você quer dizer o valor do par de valores-chave , pode

myMap.values.exists(_ == 3)
myMap.exists(_._2 == 3)

Se você quiser apenas testar a chave do par de valores-chave ,

myMap.keySet.exists(_ == "fish")
myMap.exists(_._1 == "fish")
myMap.contains("fish")

Observe que, embora as formas de tupla (por exemplo _._1 == "fish") acabem sendo mais curtas, as formas um pouco mais longas são mais explícitas sobre o que você deseja que aconteça.

Rex Kerr
fonte
13
Também vale a pena dizer que para testar a existência de uma chave, a biblioteca fornece myMap.contains ("fish")
Dave Griffith
2
@DaveGriffith - Certamente. Eu estava usando "existe", mas esse é importante o suficiente (já que é o que você deve usar) para adicionar. Eu alterei a resposta de acordo.
Rex Kerr
25

Você quer saber se o valor existe no mapa, ou a chave? Se você quiser verificar a chave, use isDefinedAt:

myMap isDefinedAt key
Daniel C. Sobral
fonte
9

você fornece um teste em que um dos valores do mapa passará, ou seja,

val mymap = Map(9->"lolo", 7->"lala")
mymap.exists(_._1 == 7) //true
mymap.exists(x => x._1 == 7 && x._2 == "lolo") //false
mymap.exists(x => x._1 == 7 && x._2 == "lala") //true

Os ScalaDocs dizem do método "Testa se um predicado é válido para alguns dos elementos deste mapa imutável.", O problema é que ele recebe uma tupla (chave, valor) em vez de dois parâmetros.

ilcavero
fonte
6

Que tal isso:

val map = Map(1 -> 'a', 2 -> 'b', 4 -> 'd')
map.values.toSeq.contains('c')  //false

Rende truese o mapa contiver cvalor.

Se você insiste em usar exists:

map.exists({case(_, value) => value == 'c'})
Tomasz Nurkiewicz
fonte
2
valuescria um novo Iterablepara que você provavelmente map.valuesIterator.contains('c')fique melhor (embora não seja tão fácil quanto map.exists(_._2 == 'c')!)
Luigi Plinge
3

De acordo com as respostas acima, observe que existe () é significativamente mais lento do que contém () (eu fiz benchmarking com um Mapa contendo 5000 chaves de string e a proporção era um x100 consistente). Sou relativamente novo em scala, mas acho que existe () está iterando em todas as chaves (ou chave, valor tupple), enquanto contém usa o acesso aleatório de Map

Rpeleg
fonte