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 中,我不需要知道它实际上在哪里。这是非常关键的性能!

Nodejs 解决方案或技巧将是惊人的!

4

4 回答 4

6

这没有错。该Array不包含这样的String,而仅包含两个Object 引用。因此,结果是正确的-1

要从包含搜索到的字符串值的对象引用中获取索引,我们可以这样

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

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

根据您的 ninja 编辑,如果您只想知道持有特定id的对象引用是否包含在该数组中,请像这样使用它

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

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

第二次编辑:如果您真的并且仅在性能之后,您可能不希望在任何搜索中都有任何函数调用开销。我会使用类似的东西

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"}。那将永远是错误的。)

我敢肯定 node 有一些花哨的方法可以做到这一点,但裸 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似乎是一个对象数组(不是 ids),它具有Id属性之一。indexOf函数用于查找匹配元素的索引。由于您传递了一个 ID 值来搜索索引,因此它没有将它作为数组中的元素找到,因此返回 false。

要解决此问题,您有两种选择:

  1. 迭代公司元素比较 ID 值,如果匹配则返回 true,否则返回 false。

  2. 在函数中使用具有所需 id 的对象作为参数indexOf。如果值大于 -1,则返回 true,否则返回 false。

于 2012-12-24T02:48:31.120 回答
0

.indexOf正在返回正确的输出;您的数组没有包含该字符串的元素。实际上,它是一个包含两个对象字面量的数组。您不需要.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 回答