JavaScript/jQuery 等效于 LINQ Any()

Posted

技术标签:

【中文标题】JavaScript/jQuery 等效于 LINQ Any()【英文标题】:JavaScript/jQuery equivalent of LINQ Any() 【发布时间】:2011-08-22 11:27:58 【问题描述】:

javascript 或 jQuery 中是否有 IEnumerable.Any(Predicate<T>) 的等价物?

我正在验证一个项目列表,如果检测到错误,我想尽早中断。我可以使用$.each 做到这一点,但我需要使用外部标志来查看是否确实找到了该项目:

var found = false;
$.each(array, function(i) 
    if (notValid(array[i])) 
        found = true;
    
    return !found;
);

有什么更好的方法?我不喜欢在 JavaScript 数组中使用普通的 for,因为它会迭代所有成员,而不仅仅是值。

【问题讨论】:

【参考方案1】:

如今,您实际上可以使用 Array.prototype.some(在 ES5 中指定)来获得相同的效果:

array.some(function(item) 
    return notValid(item);
);

【讨论】:

快速总结:some() 对数组中存在的每个元素执行一次回调函数,直到找到一个回调函数返回真值。如果找到这样的元素,some() 立即返回 true。否则,some() 返回 false。 如果你能用,这就是正确的答案。它是 Linq.Any() 的等效函数 如果你需要兼容 IE8,那么这不是一个选项。 更新:在 ES6 / ECMAScript 2015 中,您可以使用 myArray.some(c=>c) 来准确模仿 LINQ 对 .Any() 的作用。请注意,在 LINQ 中 .Any() 方法不需要委托,而 .some() 需要委托。尝试在没有委托的情况下调用 .some() 将导致错误,因为委托将未定义。【参考方案2】:

您可以使用接受谓词的 jQuery is 函数的变体:

$(array).is(function(index) 
    return notValid(this);
);

【讨论】:

我认为当用于array 时,您应该避免在is 函数中使用this。因为你不会得到原始类型(所以使用“===”的比较会失败)。我会改用array[i]。看到这个:jsfiddle.net/BYjcu/3 这很有趣(我的fiddle to confirm),但我的直觉反应是避免这种方法,因为它在不是 jQuery 选择(本机数组)的集合上运行选择函数 $.fn.is .如果有像$.is 这样的实用功能,我会觉得更安全,但这似乎是一个未记录的“功能” AFAIK jQuery 选择 原生数组(或者至少他们使用Array.prototype),并且可能有足够的代码依赖它,它永远不会改变。这句话,这个答案已经快六年了。这些天你应该使用附近显示的原生 ES5 方法,或者像 LoDash/Underscore/等。具有专门用于处理原生 JS 数组的 API。 你说得对,我没有注意到这个答案的日期。对此感到抱歉(现在我无法撤消我的反对票!)【参考方案3】:

Xion 的回答是正确的。扩展他的答案:

jQuery 的 .is(function) 与 .NET 的 IEnumerable.Any(Predicate<T>) 具有相同的行为。

来自http://docs.jquery.com/is:

根据表达式检查当前选择,如果选择的至少一个元素适合给定的表达式,则返回 true。

【讨论】:

这应该是对他们答案的评论或编辑吗?似乎只同意那个答案,添加了一些上下文?【参考方案4】:

您应该使用普通的for 循环(不是for ... in),它只会循环遍历数组元素。

【讨论】:

*可以(我想你是想说) @Simon_Weaver:不;他不应该使用for in来迭代数组。 @SLaks,你误解了 Simon_Weaver 的评论! “您可以使用普通的 for 循环。”而不是“你应该...” 嗯,它肯定说应该就在文本中。当字面上写在那里时,你不能说他们被误解了。【参考方案5】:

您可以使用 array.filter(IE 9+ 请参阅下面的链接了解更多详细信息)

[].filter(function() return true|false ;).length > 0;

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

【讨论】:

【参考方案6】:

我建议您尝试 JavaScript for in 循环。但是,请注意语法与使用 .net IEnumerable 获得的语法完全不同。这是一个小的说明性代码示例。

var names = ['Alice','Bob','Charlie','David'];
for (x in names)

    var name = names[x];
    alert('Hello, ' + name);


var cards =  HoleCard: 'Ace of Spades', VisibleCard='Five of Hearts' ;
for (x in cards)

    var position = x;
    var card = card[x];
    alert('I have a card: ' + position + ': ' + card);

【讨论】:

我相信 OP 想用 plain for (...) 迭代其所有成员for in 的使用有时可以 yield unexpected results (如果Array.prototype 已扩展,或者如果您隐式调整数组大小)。【参考方案7】:

死灵术。 如果你不能使用 array.some,你可以在 TypeScript 中创建你自己的函数:

interface selectorCallback_t<TSource> 

    (item: TSource): boolean;



function Any<TSource>(source: TSource[], predicate: selectorCallback_t<TSource> )

    if (source == null)
        throw new Error("ArgumentNullException: source");
    if (predicate == null)
        throw new Error("ArgumentNullException: predicate");

    for (let i = 0; i < source.length; ++i)
    
        if (predicate(source[i]))
            return true;
    

    return false;
 // End Function Any

转译为

function Any(source, predicate) 
 
    if (source == null)
        throw new Error("ArgumentNullException: source");
    if (predicate == null)
        throw new Error("ArgumentNullException: predicate");
    for (var i = 0; i < source.length; ++i) 
    
        if (predicate(source[i]))
            return true;
    
    return false;

用法:

var names = ['Alice','Bob','Charlie','David'];
Any(names, x => x === 'Alice');

【讨论】:

【参考方案8】:

我建议你使用$.grep() 方法。非常接近IEnumerable.Any(Predicate&lt;T&gt;)

$.grep(array, function(n, i) 
  return (n == 5);
);

这里有一个工作示例:http://jsfiddle.net/ErickPetru/BYjcu/。

2021 年更新

这个答案是 10 多年前发布的,所以强调这一点很重要:

    当它发布时,它是一个完全合理的解决方案,因为当时 JavaScript 没有原生的东西可以通过单个函数调用来解决这个问题; 原始问题带有 jQ​​uery 标签,因此基于 jQuery 的答案不仅是预期的,而且是必须的。因此投反对票根本没有意义。 从那时起,JavaScript 世界发生了很大的变化,因此,如果您不喜欢 jQuery,请使用更新的解决方案!这个是出于历史目的,并作为旧需求的参考,也许有人在使用遗留代码时仍然觉得有用。

【讨论】:

其实$.grep()更像FindAll(Predicate&lt;T&gt;) @Groo:我没说Any(Predicate&lt;T&gt;)是最接近grep()的方法,只是非常接近。我同意FindAll(Predicate&lt;T&gt;) 更接近它。但两者都在附近。

以上是关于JavaScript/jQuery 等效于 LINQ Any()的主要内容,如果未能解决你的问题,请参考以下文章

如何知道没有 iphone 和 ipad,任何 javascript/jquery 效果/插件都适用于这些?

JavaScript jQuery单击以显示/隐藏菜单,类似于桌面应用程序

JavaScript jquery - 专注于页面上的第一个文本输入字段

使用javascript / jQuery将触摸事件应用于每次点击事件

C# 等效于 Java 标点正则表达式

等效于 Riverpod 中的 ChangeNotifierProvider 小部件