Javascript相当于C#LINQselect
在这里的这个问题:
在淘汰赛中使用勾选的绑定与checkbox列表将检查所有的checkbox
我已经创build了一些checkbox使用敲除,允许从数组中select。 从上面的工作小提琴职位:
http://jsfiddle.net/NsCXJ/
有没有简单的方法来创build一个水果的ID的数组?
我用C#在家里,我会沿着selectedFruits.select(fruit=>fruit.id);
方向做些事情selectedFruits.select(fruit=>fruit.id);
是否有一些方法/现成的function做类似的JavaScript / jQuery的? 或者最简单的select是循环遍历列表并创build第二个数组? 我打算把数组发回到JSON服务器,所以我想尽量减less发送的数据。
是的, 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);
由于旧版浏览器不支持array.map,我build议你坚持使用jQuery方法。
如果您因为某种原因而更喜欢另一个,则可以随时添加一个polyfill以实现旧的浏览器支持。
您始终可以将自定义方法添加到数组原型中:
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; });
如果传递string,则使用函数构造函数的扩展版本。 有些东西可能玩弄:
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'));
更新:
由于这已成为如此受欢迎的答案,我添加类似的我的where()
+ firstOrDefault()
。 这些也可以使用基于string的函数构造函数方法(这是最快的),但这里是另一种使用对象字面量作为filter的方法:
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(prop)) 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; };
用法:
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' });
这是一个jsperftesting来比较函数构造函数与对象文字速度。 如果您决定使用前者,请记住正确地引用string。
我个人偏好是在过滤1-2个属性时使用基于对象字面值的解决scheme,并传递callback函数以进行更复杂的过滤。
将方法添加到本机对象原型时,我将以2个一般技巧结束:
-
在覆盖之前检查现有方法的发生,例如:
if(!Array.prototype.where) { Array.prototype.where = ...
-
如果您不需要支持IE8及以下版本,请使用Object.defineProperty定义方法,使其不可枚举。 如果有人用数组(首先是错误的),他们也会迭代枚举属性。 只是一个头。
我知道这是一个迟到的答案,但对我有用! 只需完成,使用$.grep
函数就可以模拟linq的where()
。
LINQ:
var maleNames = people .Where(p => p.Sex == "M") .Select(p => p.Name)
使用Javascript:
// replace where with $.grep // select with $.map var maleNames = $.grep(people, function (p) { return p.Sex == 'M'; }) .map(function (p) { return p.Name; });
既然你正在使用knockout,你应该考虑使用knockout工具函数arrayMap()
,它是其他数组实用函数。
下面是数组实用程序函数及其等价的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)
所以你可以在你的例子中做的是:
var mapped = ko.utils.arrayMap(selectedFruits, function (fruit) { return fruit.id; });
如果你想在javascript中使用LINQ类似的接口,你可以使用一个库,比如linq.js ,它提供了一个很好的LINQ方法。
var mapped = Enumerable.From(selectedFruits) .Select("$.id") // 1 of 3 different ways to specify a selector function .ToArray();
你也可以试试linq.js
在linq.js
你的
selectedFruits.select(fruit=>fruit.id);
将会
Enumerable.From(selectedFruits).Select(function (fruit) { return fruit.id; });
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); }
也在: https : //jsfiddle.net/52dpucey/
看看underscore.js ,它提供了很多类似linq的函数。 在你给你的例子中会使用map函数。
我已经在TsLinq.codeplex.com下为TypeScript构build了一个Linq库,您也可以使用它作为普通的JavaScript。 该库比Linq.js快2-3倍,并包含所有Linq方法的unit testing。 也许你可以回顾一下。
Dinqyjs有一个像linq一样的语法,并为map和indexOf等函数提供了polyfill ,并且专门用于在Javascript中处理数组。
以下是使用ES6使用Linq风格语法的JavaScript框架示例。 http://www.syntaxsuccess.com/viewarticle/554e3b38dee3b4986d7466f8
该项目通过Babelbuild立到ES5的转运。
- JavaScript:Class.method与Class.prototype.method
- jQuery $(document).ready()激发两次
- 可以用xhr.onloadreplacexhr.onreadystatechange用于AJAX调用吗?
- Nashorn和Scala未来要JS Promise转换
- 插入Google Analytics(分析)代码的最佳位置
- Javascript的正则expression式:如何把正则expression式中的variables?
- iframe shimming或ie6(及以下)selectz-index错误
- 如何在特定时间自动重新加载网页?
- 什么是最有效的node.js进程间通信库/方法?