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?



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)]


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


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.


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.


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);

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);

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)

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;
}

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);
}

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})

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);

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>

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.