【发布时间】:2013-10-28 15:48:40
【问题描述】:
对于个人挑战,我正在用 JavaScript 实现 LINQ(嗯,一组具有类似 LINQ 功能的函数)。但是,截至目前,这些函数正在立即处理数据;这对于某些函数(例如 Sum 或 Aggregate)是正确的行为,但对于其他函数(例如 Select 或 While)则不正确。
我很好奇 JavaScript 中是否有一个构造可以让我获得与 .Net 中相同的行为,其中在枚举集合或使用立即执行的函数之前不会发生真正的处理。
注意:我相信这个任务(在 JS 中实现 LINQ)已经完成了。那不是重点。这是我自己对自己的挑战,这很可能会帮助我增加对 LINQ(以及,巧合的是,JS)的理解。除了个人的熏陶,我很快就会在我的工作中使用 LINQ,可能会根据个人项目的需要使用 JS 来完成我的工作,并且我会将 JS 用于工作之外的一些事情。
编辑:似乎我吸引了不熟悉 LINQ 的人,所以我想我应该在这方面做一些解释。 LINQ 是 Language-INtegrated Query,来自 .Net。 LINQ 允许对许多数据源(包括实际的 SQL 关系数据库)进行类似 SQL 的查询,例如 LINQ to Objects,这是我想要实现的。
LINQ 的一个特性是延迟执行许多方法。如果我有一个集合 customers 并调用 var query = customers.Where(c => c.Age > 40);(或者它最终会在 JS 中,var query = customers.Where(function (c) { return c.Age > 40; });),则返回值是一个接口类型,并且集合的实际处理(返回集合仅包含 40 岁以上的客户)尚未发生。当我使用其中一种没有延迟执行的方法时(例如,query.First() 或query.ToArray()),然后所有的延迟处理都会发生。这可以是一个链,例如customers.Where(...).Skip(5).Select(...).OrderBy(...)(每个“...”都是一个函数)。
结果是这样的代码:
var collection = [1, 2, 3, 4, 5];
var query = collection.Where(function (n) { return n % 2 == 0; });
collection.push(6);
alert(query.Max());
将导致“6”。
作为附录,我目前正在通过将我的方法原型化到 Object 和 Array 上来实现这个项目,迭代
this 的元素,并跳过任何作为函数的元素。像制作 Enumerable 类这样的东西可能更好(事实上,如果需要返回函数或匿名对象等东西,我的延迟执行计划可能需要它),但这就是我目前所拥有的。我的功能通常表现为以下内容:
Object.prototype.Distinct = Array.prototype.Distinct = function (comparer) {
comparer = comparer || function (a, b) { return a == b; };
var result = [];
for (var idx in this) {
var item = this[idx];
if (typeof item == "function") continue;
if (!result.Contains(item, comparer)) result.push(item);
}
return result;
};
【问题讨论】:
-
它已经实现了:LINQ for javascript ..cheers for LINQ..;)
-
你能举一个你想支持的语法的例子吗?想象一下,您已经实现了延迟执行的 API,使用它大概会是什么样子?
-
@Anirudh,虽然它在 JS 中实现了类似 LINQ 的功能,但它没有 LINQ 的延迟执行。而且,正如我所说,我知道这已经完成了,但这是一个个人挑战。看另一个孩子写字并不能教孩子写好字。
-
延迟执行是由于 C# 中的
yield关键字。这实际上是编译器变成switch语句的语法糖。您应该能够创建一个 javascript 模拟:startbigthinksmall.wordpress.com/2008/06/09/… -
@MikeEdwards,考虑一下:
var query = myCollection.Where(...).Skip(5).Select(...);可能是一些示例代码(其中“...”是函数)。这完全可以通过从我的函数返回数组来实现,因为我的函数是在 Array 上进行原型设计的,但在 .Net 中 none 实际上会发生这种处理,直到例如我调用query.First();
标签: javascript linq