Objeto de búsqueda inversa con matriz

Digamos si tengo un objeto como este.

resourceMap = { "a": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "b": [11, 12], "c": [21, 23], "d": [54, 55, 56, 57, 510] }; 

¿Cuál es la mejor manera de averiguar si resourceId = 21 sería "c" ?

No sabemos los nombres de las claves o el número de claves. Solo coincide una vez: el significado 21 pertenecerá a una sola tecla "c" .

Estoy pensando en recorrer todas las teclas y hacer indexOf() , pero no creo que sea lo suficientemente “elegante”.

Podría usar el guión bajo, pero intente evitar e ir con lo que sea Angular o jQuery o simplemente vainilla Javascript.

Es perfectamente aceptable tener nombres de propiedades numéricas para objetos en JavaScript. Podemos usar esto para nuestra ventaja para construir un segundo objeto que mapee todo a la inversa. Esto hará que las búsquedas sean baratas.

 var reverseMap = {}; for(var propName in resourceMap) { var numsArr = resourceMap[propName]; numsArr.forEach(function(num){ reverseMap[num]=propName; }); } console.log(reverseMap[54]); //'d' 

http://jsfiddle.net/y11sbgbv/

La construcción del reverseMap también se puede hacer más “funcionalmente” (por ejemplo, sin usar efectos secundarios) de la siguiente manera:

 var reverseMap2 = Object.keys(resourceMap).reduce((acc, propName) => resourceMap[propName].reduce((a, num) => { a[num] = propName; return a; }, acc), {}); 

Preproceso en una tabla de consulta diferente

 var revMap = []; // or var revMap = {}; Object.keys(resourceMap).forEach(function(key) { resourceMap[key].forEach( function (ind) { revMap[ind] = key; }); }); console.log(revMap[21]) 

o buscar en la demanda:

 resourceMap = { "a": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "b": [11, 12], "c": [21, 23], "d": [54, 55, 56, 57, 510] }; function findMapKey (map, ind) { var match = null; Object.keys(map).some(function(key) { var test = map[key].indexOf(ind)!==-1; if (test) { match = key; } return test; }); return match; } console.log(findMapKey(resourceMap, 21)); 

Parece que los valores están ordenados, por lo que primero puede ver si la última de cada matriz es mayor que el valor que está buscando, una vez que lo encuentre, busque el valor en sí.

 for(var propName in resourceMap) { var array = resourceMap[propName]; var lastNum = array[array.length-1]; if(lastNum == 21 || (lastNum > 21 && array.indexOf(21) > -1)) { console.log(propName) break; } } 

A menos que esté trabajando con una gran cantidad de datos, su idea está bien:

  var resourceMap = { "a": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "b": [11, 12], "c": [21, 23], "d": [54, 55, 56, 57, 510] }; /** * @return resource's group, or false if no matching group is found */ var getResourceGroup = function(res) { for (var i in resourceMap) { if (resourceMap[i].indexOf(res) > -1) { return i; } } return false; } console.log(getResourceGroup(21)); 

Tratar

 resourceMap = { "a": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "b": [11, 12], "c": [21, 23], "d": [54, 55, 56, 57, 510] }; var getKey = function(val, _key) { $.each(resourceMap, function(k, v) { if ($.inArray(val, v) != -1) { _key = k } }) return _key }; getKey(21) 

jsfiddle http://jsfiddle.net/guest271314/gbnzmq51/