对于个人挑战,我正在 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;
};