问题 jQuery Grep替代方案返回一个项目


我正在看一些我正在写的jQuery代码,它对我的​​C#大脑看起来很奇怪。有更好的方法吗?

var idToLookFor = 2;
var myArray = [{id:1},{id:2},{id:3}]

var arrayItem = $.grep(myArray , function (elm) {
    return elm.id == idToLookFor;
});

var itemFound = arrayItem[0];

我可以理解grep返回一个数组,而不是它是一个查找类型函数,它是一个过滤器类型函数,所以我想问题应该是一个只返回一个项而不是一个数组的函数?


12679
2017-08-02 13:31


起源

是的,你已经在最后一行使用它了。 - Blazemonger
如果您只需要数组中的第一个匹配项,那么 循环遍历数组 直到你得到它? - NDM
我认为这可能只是一个错误[在问题中],但上述不起作用, myArray 不包含任何具有名为的属性的对象 Id - billyonecan
是的,这是一个错字:) - Jammer
@Jammer,你可以直接返回元素 grep?这样的事情 var arrayItem = $.grep(myArray , function (elm) { if(elm.id == idToLookFor) return elm; });。如果它与任何东西都不匹配,它将返回一个空数组 - Henrik Andersson


答案:


对另一个问题的回答指出,即使找到正确的答案,grep也会继续循环遍历数组。在上面的示例中不是问题,但如果您的阵列可能更大,则值得注意: 非grep解决方案

它只是一个for循环,它包含在一个返回它找到的对象的函数中。即使你坚持使用grep方法,我仍然会将你的逻辑抽象为一些可重用的函数,并将它保存在一个好的帮助文件中。

我正在发布一个修改后的答案纯粹,所以你可以在决定是否要关注链接之前看到我的意思:

for (var i = 0, len = myArray.length; i < len; i++) 
{
    if (myArray[i].id === idToLookFor)
    {
        return myArray[i]; // Return as soon as the object is found
    }
}

10
2017-08-02 15:08





好吧,如果你喜欢使用jQuery泛型函数样式,你可以在你的个人库中添加这样的东西:

$.extend( {
    findFirst: function( elems, validateCb ){
        var i;
        for( i=0 ; i < elems.length ; ++i ) {
            if( validateCb( elems[i], i ) )
                return elems[i];
        }
        return undefined;
    }
} );

用于您的示例:

var result = $.findFirst( myArray, function(elm) {
    return elm.id == idToLookFor;
});

当然,您可以使用自己的命名空间...

我认为你关心的是 代码可读性。我认为直接使用语言循环解决方案也很好。

你也可能会担心 浪费,因为没有必要为此维护另一个数组结构,但至少对于你的例子它似乎是一个 微优化 问题。


3
2017-10-21 18:35





扩展Blazemonger的评论:

var itemFound = myArray[idToLookFor - 1]

如果我正确理解你的问题,应该找到你正在寻找的物品。请注意-1表示从1开始编制索引

编辑:这也假设数组将始终按ID中的升序排序,就像在您的问题中一样。如果你的id确实很好地增加但是数组最初没有按它们排序,请参阅: 在JavaScript中按字符串属性值对对象数组进行排序


1
2017-08-02 13:46



如果项目确实已经排序,这是一个很好的解决方案。 - Jammer
我不认为数组项“id”属性与数组中的索引有任何关系。 Blazemonger所说的是要获得数组中的第一个元素,只需使用即可 [0], 就这样。 - Didier Ghys
啊,我看,我只是认为id从1开始增加1,而不仅仅是一个任意数字。如果是这种情况,则在使用我的解决方案之前,可以通过id值对数组进行排序。 stackoverflow.com/questions/1129216/... - underbar


如果你有一个对象数组,这将做:

var result = myArray.filter(function(v) {
    return v.id === idToLookFor; 
})[0];

对于一个简单的数组你可以使用 inArray 。它返回项目所在的数组的键!

var itemFound = myArray [$。inArray(idToLookFor,myArray)];


0
2017-08-02 13:40



这仅适用于值数组。问题中的数组是一个对象数组。 - Didier Ghys
如果你只需要第一次出现,你为什么要过滤整个数组呢? for循环更快更好 - NDM
你是对的,因为循环显然是直接和快速的:) - Aditya


请用

var idToLookFor = 2;
var myArray = [{id:1},{id:2},{id:3}]

var arrayItem = $.map(myArray , function (elm) {
    if(elm.id == idToLookFor)
      return elm.id ;
});

var itemFound = arrayItem[0];

0
2017-12-21 05:09