2

オブジェクトの配列でのindexOfの使用についてはよくわかりません

動作していないコードは次のとおりです。

if (res.locals.company.companies.indexOf(req.query.companyId) >= 0) return next()

if条件は常にfalseを返します。

私もコンソールでテストしましたが、実際には間違っています:

>> var zio = { __v: 1,
  _id: '50bc0238049a1ff10b000001',
  companies: 
   [ { _id: '50bc01938f164ee80b000001', name: 'Test' },
     { _id: '50bc01ac4e860ee90b000001', name: 'zio' } ],
}

>> zio.companies.indexOf("50bc01938f164ee80b000001")
-1

それは本当のはずですが。

不思議なアンダースコアユーティリティを使用する必要がありますか?

更新/明確化:私の目的は、50bc01938f164ee80b000001がIDの1つに存在するかどうかを確認することです。実際に、それがどこにあるかを知る必要はありません。これは非常にパフォーマンスが重要です。

Nodejsのソリューションやヒントは素晴らしいでしょう!

4

4 に答える 4

6

それは間違いではありません。その配列にはそのような文字列は含まれていませんが、 2つのオブジェクト参照のみが含まれています。したがって、結果は正しくなり-1ます。

検索された文字列値を含むオブジェクト参照からインデックスを取得するには、次のようになります。

var index;
zio.companies.some(function( obj, idx ) {
    if( obj._id === '50bc01938f164ee80b000001' ) {
        index = idx;
        return true;
    }
});

console.log('index is: ', index);

忍者の編集に基づいて、特定のIDを保持するオブジェクト参照がその配列に含まれているかどうかを知りたい場合は、次のように使用します。

var check = zio.companies.filter(function( obj ) {
    return obj._id === '50bc01938f164ee80b000001';
});

if( check.length ) {
    console.log('yep');
} else {
    console.log('nope');
}

2番目の編集:パフォーマンスが本当に必要な場合は、検索で関数呼び出しのオーバーヘッドを発生させたくないでしょう。私は次のようなものを使用します

function inObject(arr, search) {
    var len = arr.length;
    while( len-- ) {
        if(arr[len]._id === search)
           return true;
    }
}

if( inObject( zio.companies, 'AAA' ) ) {
}

このコードは、ここで提供されているスニペットよりも数桁優れています。こちらをご覧ください

于 2012-12-24T02:45:26.980 に答える
0

_id要素をループして、等しいかどうかを確認する必要があります。

indexOfは厳密な同等性をチェックし、それらのオブジェクトはもちろんその文字列と等しくありません。(これはと同じロジック"hello" === {foo: "hello"}です。これは常にfalseになります。)

私はノードでそれを行うためのいくつかの素晴らしい方法があると確信していますが、裸のJSの方法は次のとおりです:

var i,
    arr = [{foo: 'bar'}, {foo: 'baz'}],
    idx = -1;
for (i = 0; i < arr.length; ++i) {
    if (arr[i].foo === 'bar') {
        idx = i;
        break;
    }
}

これを関数に簡単に変換することもできます。

function indexOf(arr, pred) {
    for (var i = 0; i < arr.length; ++i) {
        if (pred(arr)) {
            return i;
        }
    }
    return -1;
}

これにより、より詳細な使用法が得られます(パフォーマンスが少し低下します)が、頻繁に行う必要がある場合は、柔軟性が少し高くなる可能性があります。

console.log(indexOf(arr, function(elem) { return elem.foo === 'bar'; });
于 2012-12-24T02:45:32.270 に答える
0

あなたcompaniesは(IDではなく)オブジェクトの配列のようIdで、属性の1つとして持っています。indexOf関数は、一致する要素のインデックスを見つけるために使用されます。インデックスを検索するためにID値を渡しているため、配列上の要素としてID値が見つからないため、falseが返されます。

この問題を解決するには、次の2つのオプションがあります。

  1. 一致した場合はtrueを返し、そうでない場合はfalseを返す場合は、companys要素を繰り返してID値を比較します。

  2. 関数の引数として、目的のIDを持つオブジェクトを使用しますindexOf。値が-1より大きい場合はtrueを返し、そうでない場合はfalseを返します。

于 2012-12-24T02:48:31.120 に答える
0

.indexOf正しい出力を返しています。配列にはその文字列を含む要素がありません。実際、これは2つのオブジェクトリテラルを保持する配列です。オブジェクトは必要ありません.indexOf。代わりに、独自の関数を作成する必要があります。

 var inObject = function( object, val ) {

     for (var i in object) { if ( object.hasOwnProperty(i) ) {

             if ( obj[i] === val ) {

                 return true;
             }

         }

     }
     return false;
 };

>>> inObject( zio.companies[0], '50bc01938f164ee80b000001' );
    : true
于 2012-12-24T02:48:36.567 に答える