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 想用 plainfor
(...) 迭代其所有成员 说 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<T>)
:
$.grep(array, function(n, i)
return (n == 5);
);
这里有一个工作示例:http://jsfiddle.net/ErickPetru/BYjcu/。
2021 年更新
这个答案是 10 多年前发布的,所以强调这一点很重要:
-
当它发布时,它是一个完全合理的解决方案,因为当时 JavaScript 没有原生的东西可以通过单个函数调用来解决这个问题;
原始问题带有 jQuery 标签,因此基于 jQuery 的答案不仅是预期的,而且是必须的。因此投反对票根本没有意义。
从那时起,JavaScript 世界发生了很大的变化,因此,如果您不喜欢 jQuery,请使用更新的解决方案!这个是出于历史目的,并作为旧需求的参考,也许有人在使用遗留代码时仍然觉得有用。
【讨论】:
其实$.grep()
更像FindAll(Predicate<T>)
。
@Groo:我没说Any(Predicate<T>)
是最接近grep()
的方法,只是非常接近。我同意FindAll(Predicate<T>)
更接近它。但两者都在附近。以上是关于JavaScript/jQuery 等效于 LINQ Any()的主要内容,如果未能解决你的问题,请参考以下文章
如何知道没有 iphone 和 ipad,任何 javascript/jquery 效果/插件都适用于这些?
JavaScript jQuery单击以显示/隐藏菜单,类似于桌面应用程序
JavaScript jquery - 专注于页面上的第一个文本输入字段