trova l'indice dell'array di un oggetto con un valore chiave specifico in carattere di sottolineatura


91

In sottolineatura, posso trovare con successo un elemento con un valore chiave specifico

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

ma come faccio a trovare in quale indice di matrice si è verificato quell'oggetto?



Grazie - questo è utile - ma nell'esempio elencato stai cercando un singolo numero in un array di numeri - Sto cercando un valore chiave in un array di oggetti. Questa funzione lo accontenterà?
mheavers

2
Che si tratti di un test numerico o del predicato di equità della tua proprietà non importa, sì.
Bergi

Prova findIndex:var dataIndex = _.findIndex(tv, { id: voteID })
Tom Söderlund

Considerare di accettare la risposta che fornisce una soluzione di sottolineatura , come richiesto nella domanda.
Nigel B. Peck

Risposte:


28

Non so se esiste un metodo di sottolineatura esistente che lo fa, ma puoi ottenere lo stesso risultato con un semplice javascript.

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

Quindi puoi semplicemente fare:

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


4
Perché non return -1;di default?
Radu Chiriac

171

findIndex è stato aggiunto in 1.8:

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

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

In alternativa, funziona anche se non ti dispiace creare un altro elenco temporaneo:

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

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


Non sono sicuro del carattere di sottolineatura ma in lodash non hai bisogno di una funzione anonima, semplicemente funzionerà, index = _.findIndex(tv, {id: voteID})funziona anche se la tvraccolta ha valori più complicati (più di una semplice idproprietà)
Scott Jungwirth

1
Solo un punto usando spennare è molto più lento. Io a causa della sua traversata extra. jsperf.com/compare-find-index
Farshid Saberi

38

Se vuoi rimanere con il carattere di sottolineatura in modo che la tua funzione del predicato possa essere più flessibile, ecco 2 idee.

Metodo 1

Poiché il predicato per _.findriceve sia il valore che l'indice di un elemento, puoi utilizzare l'effetto collaterale per recuperare l'indice, in questo modo:

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

Metodo 2

Guardando la fonte del carattere di sottolineatura, ecco come _.findviene implementato:

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

Per renderlo una findIndexfunzione, è sufficiente sostituire la riga result = value;con result = index;Questa è la stessa idea del primo metodo. L'ho incluso per sottolineare che il carattere di sottolineatura utilizza anche effetti collaterali da implementare _.find.


37

Lo-Dash , che estende Underscore, ha findIndex metodo , che può trovare l'indice di una data istanza, o da un dato predicato, o secondo le proprietà di un dato oggetto.

Nel tuo caso, farei:

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

Provaci.


findIntex è un metodo da lo-dash, non da underscore
Wallysson Nunes

4
@WallyssonNunes Questo è esattamente quello che ho scritto - "Lo-Dash, che estende Underscore, ha il metodo findIndex"
splintor

3
Questo fa ora parte della libreria di sottolineatura standard, a partire dalla versione 1.8.0: underscorejs.org/#1.8.0
Gage Trader

10

Se il tuo ambiente di destinazione supporta ES2015 (o hai un passaggio transpile, ad esempio con Babel), puoi utilizzare il nativo Array.prototype.findIndex ().

Dato il tuo esempio

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

4

puoi usare il indexOfmetodo dalodash

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

Keepin 'semplice:

// 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

Oppure, per chi non odia, la variante CoffeeScript:

findIndex = (arr, cond) ->
  for i, x of arr
    return parseInt(i) if cond(x)

1
meglio sarebbereturn parseInt(i) for i, x of array when cond(x)
meagar

1
come è semplice rispetto alle risposte precedenti ??
ncubica

2

Questo serve per aiutare gli lodashutenti. controlla se la tua chiave è presente facendo:

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

1

La soluzione più semplice è usare lodash:

  1. Installa lodash:

npm install --save lodash

  1. Usa il metodo findIndex:

const _ = require ('lodash');

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

0

Se ti aspetti più corrispondenze e quindi è necessario restituire un array, prova:

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

Se il valore della proprietà è univoco e hai bisogno dell'indice della corrispondenza, prova:

_.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

Ho ottenuto un caso simile ma al contrario è trovare la chiave utilizzata in base all'indice di un determinato oggetto. Potrei trovare una soluzione in underscore usando Object.valuesper restituire l'oggetto a un array per ottenere l'indice verificato.

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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.