encontrar el índice de matriz de un objeto con un valor clave específico en subrayado

91

En subrayado, puedo encontrar correctamente un artículo con un valor clave específico

var tv = [{id:1},{id:2}]
var voteID = 2;
var data = _.find(tv, function(voteItem){ return voteItem.id == voteID; });
//data = { id: 2 }

pero, ¿cómo encuentro en qué índice de matriz ocurrió ese objeto?

mheavers
fuente
Gracias, esto es útil, pero en el ejemplo enumerado está buscando un solo número en una matriz de números, estoy buscando un valor clave en una matriz de objetos. ¿Esta función se adaptará a eso?
mheavers
2
No importa si se trata de una prueba numérica o de su predicado de igualdad de propiedad, sí.
Bergi
Prueba findIndex:var dataIndex = _.findIndex(tv, { id: voteID })
Tom Söderlund
Considere aceptar la respuesta que brinda una solución de subrayado , como se solicita en la pregunta.
Nigel B. Peck

Respuestas:

28

No sé si existe un método de subrayado existente que haga esto, pero puede lograr el mismo resultado con JavaScript simple.

Array.prototype.getIndexBy = function (name, value) {
    for (var i = 0; i < this.length; i++) {
        if (this[i][name] == value) {
            return i;
        }
    }
    return -1;
}

Entonces puedes simplemente hacer:

var data = tv[tv.getIndexBy("id", 2)]

tewathia
fuente
4
¿Por qué no return -1;por defecto?
Radu Chiriac
171

findIndex fue agregado en 1.8:

index = _.findIndex(tv, function(voteItem) { return voteItem.id == voteID })

Ver: http://underscorejs.org/#findIndex

Alternativamente, esto también funciona, si no le importa hacer otra lista temporal:

index = _.indexOf(_.pluck(tv, 'id'), voteId);

Ver: http://underscorejs.org/#pluck

Ropez
fuente
No estoy seguro sobre el subrayado, pero en lodash no necesita una función anónima, simplemente index = _.findIndex(tv, {id: voteID})funcionará, también funciona si la tvcolección tiene valores más complicados (más que solo una idpropiedad)
Scott Jungwirth
1
Solo un punto usando el desplumado es mucho más lento. Yo por su travesía extra. jsperf.com/compare-find-index
Farshid Saberi
38

Si desea permanecer con guión bajo para que su función de predicado pueda ser más flexible, aquí hay 2 ideas.

Método 1

Dado que el predicado para _.findrecibe tanto el valor como el índice de un elemento, puede usar el efecto secundario para recuperar el índice, así:

var idx;
_.find(tv, function(voteItem, voteIdx){ 
   if(voteItem.id == voteID){ idx = voteIdx; return true;}; 
});

Método 2

Mirando la fuente de subrayado, así es como _.findse implementa:

_.find = _.detect = function(obj, predicate, context) {
  var result;
  any(obj, function(value, index, list) {
    if (predicate.call(context, value, index, list)) {
      result = value;
      return true;
    }
  });
  return result;
};

Para hacer de esto una findIndexfunción, simplemente reemplace la línea result = value;con result = index;Esta es la misma idea que el primer método. Lo incluí para señalar que el subrayado también usa efectos secundarios para implementar _.find.

lastoneisbearfood
fuente
37

Lo-Dash , que extiende Underscore, tiene el método findIndex , que puede encontrar el índice de una instancia dada, o por un predicado dado, o según las propiedades de un objeto dado.

En tu caso, yo haría:

var index = _.findIndex(tv, { id: voteID });

Darle una oportunidad.

férula
fuente
findIntex es un método de lo-dash, no de subrayado
Wallysson Nunes
4
@WallyssonNunes Esto es exactamente lo que escribí - "Lo-Dash, que extiende el subrayado, tiene el método findIndex"
splintor
3
Esto ahora es parte de la biblioteca de subrayado estándar, a partir de la versión 1.8.0: underscorejs.org/#1.8.0
Gage Trader
10

Si su entorno de destino es compatible con ES2015 (o tiene un paso de transpilación, por ejemplo, con Babel), puede utilizar el Array.prototype.findIndex () nativo.

Dado tu ejemplo

const array = [ {id:1}, {id:2} ]
const desiredId = 2;
const index = array.findIndex(obj => obj.id === desiredId);
Craigmichaelmartin
fuente
4

puedes usar el indexOfmétodo delodash

var tv = [{id:1},{id:2}]
var voteID = 2;
var data = _.find(tv, function(voteItem){ return voteItem.id == voteID; });
var index=_.indexOf(tv,data);
Amil Sajeev
fuente
3

Manteniéndolo simple:

// Find the index of the first element in array
// meeting specified condition.
//
var findIndex = function(arr, cond) {
  var i, x;
  for (i in arr) {
    x = arr[i];
    if (cond(x)) return parseInt(i);
  }
};

var idIsTwo = function(x) { return x.id == 2 }
var tv = [ {id: 1}, {id: 2} ]
var i = findIndex(tv, idIsTwo) // 1

O, para los que no odian, la variante CoffeeScript:

findIndex = (arr, cond) ->
  for i, x of arr
    return parseInt(i) if cond(x)
joyrexus
fuente
1
mejor seríareturn parseInt(i) for i, x of array when cond(x)
meagar
1
¿Cómo es esto simple que las respuestas anteriores?
ncubica
2

Esto es para ayudar a los lodashusuarios. compruebe si su clave está presente haciendo:

hideSelectedCompany(yourKey) {
 return _.findIndex(yourArray, n => n === yourKey) === -1;
}
Syed
fuente
1

La solución más simple es usar lodash:

  1. Instalar lodash:

npm install --save lodash

  1. Utilice el método findIndex:

const _ = require ('lodash');

findIndexByElementKeyValue = (elementKeyValue) => {
  return _.findIndex(array, arrayItem => arrayItem.keyelementKeyValue);
}
Jackkobec
fuente
0

Si espera múltiples coincidencias y, por lo tanto, necesita que se devuelva una matriz, intente:

_.where(Users, {age: 24})

Si el valor de la propiedad es único y necesita el índice de la coincidencia, intente:

_.findWhere(Users, {_id: 10})
Ketan
fuente
0
Array.prototype.getIndex = function (obj) {
    for (var i = 0; i < this.length; i++) {
        if (this[i][Id] == obj.Id) {
            return i;
        }
    }
    return -1;
}

List.getIndex(obj);
Chinna Amara
fuente
0

Tengo un caso similar pero al contrario es encontrar la clave utilizada en función del índice de un objeto dado. Pude encontrar una solución en el subrayado usando Object.valuespara devolver el objeto a una matriz para obtener el índice producido.

var tv = {id1:1,id2:2};
var voteIndex = 1;
console.log(_.findKey(tv, function(item) {
  return _.indexOf(Object.values(tv), item) == voteIndex;
}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>

Chetabahana
fuente