jQuery Javascript 等效于 C# LINQ Select
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18936774/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript Equivalent to C# LINQ Select
提问by Chris Nevill
Following this question here :
在此问题之后:
Using the checked binding in knockout with a list of checkboxes checks all the checkboxes
I've created some checkboxes using knockout that allow selection from an array. working fiddle taken from above post:
我使用淘汰赛创建了一些复选框,允许从数组中进行选择。从上面的帖子中提取的工作小提琴:
Is there a simple way of creating an array of just the fruit's ID's?
有没有一种简单的方法来创建一个只包含水果 ID 的数组?
I'm more at home with C# where I would do something along the lines of selectedFruits.select(fruit=>fruit.id);
我更喜欢使用 C# 在那里我会做一些类似的事情 selectedFruits.select(fruit=>fruit.id);
Is there some method/ready made function for doing something similar with javascript/jquery? Or would the simplest option be to loop through the list and create a second array? I intend to post the array back to the server in JSON so am trying to minimize the data sent.
是否有一些方法/现成的功能可以与 javascript/jquery 做类似的事情?或者最简单的选择是遍历列表并创建第二个数组?我打算将数组以 JSON 格式发回服务器,因此我试图尽量减少发送的数据。
回答by Johan
Yes, Array.map()or $.map()does the same thing.
是的,Array.map()或$.map()做同样的事情。
//array.map:
var ids = this.fruits.map(function(v){
return v.Id;
});
//jQuery.map:
var ids2 = $.map(this.fruits, function (v){
return v.Id;
});
console.log(ids, ids2);
Since array.map isn't supported in older browsers, I suggest that you stick with the jQuery method.
由于旧浏览器不支持 array.map,我建议您坚持使用 jQuery 方法。
If you prefer the other one for some reason you could always add a polyfill for old browser support.
如果您出于某种原因更喜欢另一个,您可以随时添加一个 polyfill 以支持旧浏览器。
You can always add custom methods to the array prototype as well:
您也可以随时向数组原型添加自定义方法:
Array.prototype.select = function(expr){
var arr = this;
//do custom stuff
return arr.map(expr); //or $.map(expr);
};
var ids = this.fruits.select(function(v){
return v.Id;
});
An extended version that uses the function constructor if you pass a string. Something to play around with perhaps:
如果传递字符串,则使用函数构造函数的扩展版本。也许可以玩的东西:
Array.prototype.select = function(expr){
var arr = this;
switch(typeof expr){
case 'function':
return $.map(arr, expr);
break;
case 'string':
try{
var func = new Function(expr.split('.')[0],
'return ' + expr + ';');
return $.map(arr, func);
}catch(e){
return null;
}
break;
default:
throw new ReferenceError('expr not defined or not supported');
break;
}
};
console.log(fruits.select('x.Id'));
Update:
更新:
Since this has become such a popular answer, I'm adding similar my where()
+ firstOrDefault()
. These could also be used with the string based function constructor approach (which is the fastest), but here is another approach using an object literal as filter:
由于这已成为如此受欢迎的答案,因此我添加了类似的 my where()
+ firstOrDefault()
。这些也可以与基于字符串的函数构造函数方法一起使用(这是最快的),但这是另一种使用对象文字作为过滤器的方法:
Array.prototype.where = function (filter) {
var collection = this;
switch(typeof filter) {
case 'function':
return $.grep(collection, filter);
case 'object':
for(var property in filter) {
if(!filter.hasOwnProperty(property))
continue; // ignore inherited properties
collection = $.grep(collection, function (item) {
return item[property] === filter[property];
});
}
return collection.slice(0); // copy the array
// (in case of empty object filter)
default:
throw new TypeError('func must be either a' +
'function or an object of properties and values to filter by');
}
};
Array.prototype.firstOrDefault = function(func){
return this.where(func)[0] || null;
};
Usage:
用法:
var persons = [{ name: 'foo', age: 1 }, { name: 'bar', age: 2 }];
// returns an array with one element:
var result1 = persons.where({ age: 1, name: 'foo' });
// returns the first matching item in the array, or null if no match
var result2 = persons.firstOrDefault({ age: 1, name: 'foo' });
Here is a jsperf testto compare the function constructor vs object literal speed. If you decide to use the former, keep in mind to quote strings correctly.
这是一个jsperf 测试,用于比较函数构造函数与对象文字速度。如果您决定使用前者,请记住正确引用字符串。
My personal preference is to use the object literal based solutions when filtering 1-2 properties, and pass a callback function for more complex filtering.
我个人的偏好是在过滤 1-2 个属性时使用基于对象字面量的解决方案,并传递回调函数以进行更复杂的过滤。
I'll end this with 2 general tips when adding methods to native object prototypes:
在向本机对象原型添加方法时,我将用 2 个一般提示结束本文:
Check for occurrence of existing methods before overwriting e.g.:
if(!Array.prototype.where) { Array.prototype.where = ...
If you don't need to support IE8 and below, define the methods using Object.definePropertyto make them non-enumerable. If someone used
for..in
on an array (which is wrong in the first place) they will iterate enumerable properties as well. Just a heads up.
在覆盖之前检查现有方法的出现,例如:
if(!Array.prototype.where) { Array.prototype.where = ...
如果您不需要支持 IE8 及以下版本,请使用Object.defineProperty定义方法以使其不可枚举。如果有人
for..in
在数组上使用(首先是错误的),他们也会迭代可枚举的属性。只是抬头。
回答by Stefano Altieri
I know it is a late answer but it was useful to me! Just to complete, using the $.grep
function you can emulate the linq where()
.
我知道这是一个迟到的答案,但它对我很有用!只是为了完成,使用$.grep
您可以模拟 linq的功能where()
。
Linq:
林克:
var maleNames = people
.Where(p => p.Sex == "M")
.Select(p => p.Name)
Javascript:
Javascript:
// replace where with $.grep
// select with $.map
var maleNames = $.grep(people, function (p) { return p.Sex == 'M'; })
.map(function (p) { return p.Name; });
回答by Jeff Mercado
Since you're using knockout, you should consider using the knockout utility function arrayMap()
and it's other array utility functions.
由于您使用的是淘汰赛,您应该考虑使用淘汰赛实用程序函数arrayMap()
,它是其他数组实用程序函数。
Here's a listing of array utility functions and their equivalent LINQ methods:
这是数组实用程序函数及其等效 LINQ 方法的列表:
arrayFilter() -> Where()
arrayFirst() -> First()
arrayForEach() -> (no direct equivalent)
arrayGetDistictValues() -> Distinct()
arrayIndexOf() -> IndexOf()
arrayMap() -> Select()
arrayPushAll() -> (no direct equivalent)
arrayRemoveItem() -> (no direct equivalent)
compareArrays() -> (no direct equivalent)
So what you could do in your example is this:
所以你可以在你的例子中做的是:
var mapped = ko.utils.arrayMap(selectedFruits, function (fruit) {
return fruit.id;
});
If you want a LINQ like interface in javascript, you could use a library such as linq.jswhich offers a nice interface to many of the LINQ methods.
如果您想在 javascript 中使用类似 LINQ 的接口,您可以使用诸如linq.js 之类的库,它为许多 LINQ 方法提供了一个很好的接口。
var mapped = Enumerable.From(selectedFruits)
.Select("$.id") // 1 of 3 different ways to specify a selector function
.ToArray();
回答by July.Tech
The ES6 way:
ES6方式:
let people = [{firstName:'Alice',lastName:'Cooper'},{firstName:'Bob',age:'Dylan'}];
let names = Array.from(people, p => p.firstName);
for (let name of names) {
console.log(name);
}
also at: https://jsfiddle.net/52dpucey/
回答by Anik Islam Abhi
回答by Michael Baarz
I have build a Linq library for TypeScript under TsLinq.codeplex.comthat you can use for plain javascript too. That library is 2-3 times faster than Linq.js and contains unit tests for all Linq methods. Maybe you could review that one.
我在TsLinq.codeplex.com下为 TypeScript 构建了一个 Linq 库,您也可以将其用于纯 javascript。该库比 Linq.js 快 2-3 倍,并包含所有 Linq 方法的单元测试。也许你可以回顾一下那个。
回答by Gruff Bunny
Take a peek at underscore.jswhich provides many linq like functions. In the example you give you would use the map function.
看一看underscore.js,它提供了许多类似 linq 的功能。在您提供的示例中,您将使用 map 函数。
回答by razon
You can try manipula
package, which implement all of C# LINQ methods and save its syntax:
https://github.com/litichevskiydv/manipula
你可以试试manipula
包,它实现了所有的 C# LINQ 方法并保存了它的语法:https:
//github.com/litichevskiydv/manipula
https://www.npmjs.com/package/manipula
https://www.npmjs.com/package/manipula
Your example selectedFruits.select(fruit=>fruit.id);
will be implemented with manipula as
您的示例selectedFruits.select(fruit=>fruit.id);
将使用操作符实现为
Manipula.from(selectedFruits).select(fruit=>fruit.id);
回答by Siderite Zackwehdex
I am answering the title of the question rather than the original question which was more specific.
我正在回答问题的标题,而不是更具体的原始问题。
With the new features of Javascript like iterators and generator functions and objects, something like LINQ for Javascript becomes possible. Note that linq.js, for example, uses a completely different approach, using regular expressions, probably to overcome the lack of support in the language at the time.
有了迭代器、生成器函数和对象等 Javascript 的新特性,像 LINQ for Javascript 这样的东西成为可能。请注意,以 linq.js 为例,它使用了一种完全不同的方法,即使用正则表达式,这可能是为了克服当时该语言缺乏支持的问题。
With that being said, I've written a LINQ library for Javascript and you can find it at https://github.com/Siderite/LInQer. Comments and discussion at https://siderite.dev/blog/linq-in-javascript-linqer.
话虽如此,我已经为 Javascript 编写了一个 LINQ 库,您可以在https://github.com/Siderite/LInQer 上找到它。https://siderite.dev/blog/linq-in-javascript-linqer 上的评论和讨论。
From previous answers, only Manipula seems to be what one would expect from a LINQ port in Javascript.
从以前的答案来看,似乎只有 Manipula 是人们对 Javascript 中的 LINQ 端口所期望的。