alt çizgide belirli bir anahtar değerine sahip bir nesnenin dizi dizinini bulun


91

Alt çizgide, belirli bir anahtar değerine sahip bir öğeyi başarıyla bulabilirim

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

ama bu nesnenin hangi dizi dizininde oluştuğunu nasıl bulabilirim?



Teşekkürler - bu kullanışlıdır - ancak listelenen örnekte, bir sayı dizisinde tek bir sayı arıyorsunuz - Bir dizi nesnede bir anahtar değer arıyorum. Bu işlev bunu karşılayacak mı?
mheavers

2
Bunun sayısal bir test veya mülk eşitliği yükleminizin önemi yok, evet.
Bergi

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

Lütfen soruda talep edildiği gibi Alt Çizgi çözümü sağlayan yanıtı kabul etmeyi düşünün .
Nigel

Yanıtlar:


28

Bunu yapan mevcut bir alt çizgi yöntemi olup olmadığını bilmiyorum, ancak aynı sonucu düz javascript ile elde edebilirsiniz.

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

O zaman şunları yapabilirsiniz:

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


4
Neden return -1;varsayılan olarak a değil ?
Radu Chiriac

171

findIndex 1.8'de eklendi:

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

Bakınız: http://underscorejs.org/#findIndex

Alternatif olarak, başka bir geçici liste oluşturmanın sakıncası yoksa bu da işe yarar:

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

Bakınız: http://underscorejs.org/#pluck


Alt çizgi konusunda emin değilim ama Lodash'ta anonim bir işleve ihtiyacınız yok, sadece index = _.findIndex(tv, {id: voteID})işe yarayacak, ayrıca tvkoleksiyonun daha karmaşık değerleri varsa (sadece bir idmülkten daha fazlası ) işe yarayacak
Scott Jungwirth

1
Sadece koparma kullanarak bir nokta çok daha yavaştır. Ekstra geçişinden dolayı ben. jsperf.com/compare-find-index
Farshid Saberi

38

Altçizgi ile kalmak istiyorsanız, böylece yüklem fonksiyonunuz daha esnek olabilir, işte 2 fikir.

Yöntem 1

Koşul koşulu _.findbir öğenin hem değerini hem de dizinini aldığından, aşağıdaki gibi dizini almak için yan etkiyi kullanabilirsiniz:

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

Yöntem 2

Alt çizgi kaynağına bakıldığında, _.findşu şekilde uygulanır:

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

Bunu bir findIndexişlev yapmak için , satırı result = value;ile değiştirin result = index;Bu, ilk yöntemle aynı fikirdir. Alt çizginin de uygulamak için yan etkiyi kullandığını belirtmek için ekledim _.find.


37

Alt Çizgiyi genişleten Lo-Dash , belirli bir örneğin dizinini veya belirli bir koşula göre veya belirli bir nesnenin özelliklerine göre bulabilen findIndex yöntemine sahiptir .

Senin durumunda yapardım:

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

Bir şans ver.


findIntex, alt çizgiden değil, lo-dash'den bir yöntemdir
Wallysson Nunes

4
@WallyssonNunes Tam olarak yazdığım şey bu - "Lo-Dash, Alt Çizgiyi genişleten, findIndex yöntemine sahip"
splintor

3
Bu, 1.8.0 sürümünden itibaren standart alt çizgi kitaplığının bir parçasıdır: altçizgi.org/#
Gage Trader

10

Hedef ortamınız ES2015'i destekliyorsa (veya bir aktarım adımınız varsa, örneğin Babel ile), yerel Array.prototype.findIndex () 'i kullanabilirsiniz.

Örneğinize göre

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

4

indexOfyöntemini kullanabilirsinizlodash

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

Basit tutmak:

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

Veya nefret etmeyenler için CoffeeScript varyantı:

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

1
daha iyi olurdureturn parseInt(i) for i, x of array when cond(x)
meagar

1
bu nasıl önceki cevaplardan daha basit?
ncubica

2

Bu, lodashkullanıcılara yardımcı olmak içindir . yaparak anahtarınızın mevcut olup olmadığını kontrol edin:

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

1

En basit çözüm, lodash kullanmaktır:

  1. Lodash'ı yükleyin:

npm install --save lodash

  1. FindIndex yöntemini kullanın:

const _ = required ('lodash');

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

0

Birden fazla eşleşme bekliyorsanız ve bu nedenle döndürülecek bir diziye ihtiyacınız varsa, şunu deneyin:

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

Özellik değeri benzersizse ve eşleşmenin dizinine ihtiyacınız varsa, şunu deneyin:

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

Benzer bir durumla karşılaştım ama tam tersi, belirli bir nesnenin indeksine dayalı olarak kullanılan anahtarı bulmak. Ben çözümü bulabiliriz çizgi kullanarak Object.valuesendeksi oluştu almak için bir dizi içinde döndürür nesneye.

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>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.