等效于C#LINQ Select的Javascript

2020/11/16 06:22 · javascript ·  · 0评论

在这里跟随这个问题:

在淘汰表中使用选中的绑定和复选框列表会检查所有复选框

我使用敲除创建了一些复选框,这些复选框允许从数组中进行选择。从上方发布的工作提琴:

http://jsfiddle.net/NsCXJ/

是否有一种简单的方法来创建仅水果ID的数组?

我在C#上更在家,我会按照 selectedFruits.select(fruit=>fruit.id);

是否有一些方法/现成的函数可以执行与javascript / jquery类似的操作?还是最简单的选择是遍历列表并创建第二个数组?我打算将数组以JSON的形式发送回服务器,因此尝试最小化发送的数据。

是的,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);

http://jsfiddle.net/NsCXJ/1/

由于旧版浏览器不支持array.map,因此建议您坚持使用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;
});

如果传递字符串,则使用函数构造函数的扩展版本。可能玩的东西:

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'));

http://jsfiddle.net/aL85j/

更新:

由于这已成为一个流行的答案,因此我要添加类似的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;
};

用法:

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' }); 

这是一个jsperf测试,用于比较函数构造函数与对象文字速度。如果决定使用前者,请记住正确引用字符串。

我个人的喜好是在过滤1-2个属性时使用基于对象文字的解决方案,并为更复杂的过滤传递回调函数。

在向本地对象原型添加方法时,我将以2条一般性技巧作为结尾:

  1. 在覆盖之前检查是否存在现有方法,例如:

    if(!Array.prototype.where) {
    Array.prototype.where = ...

  2. 如果不需要支持IE8或更低版本,请使用Object.defineProperty定义方法以使其不可枚举。如果有人for..in在数组上使用(首先是错误的),他们也会迭代可枚举的属性。只是抬起头。

我知道这是一个较晚的答案,但对我有用!只需完成,就可以使用该$.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; });

由于使用的是淘汰赛,因此应考虑使用淘汰赛实用程序功能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();

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/

您也可以尝试 linq.js

linq.js你的

selectedFruits.select(fruit=>fruit.id);

将会

Enumerable.From(selectedFruits).Select(function (fruit) { return fruit.id;  });

我已经在TsLinq.codeplex.com下为TypeScript构建了一个Linq库,您也可以将其用于纯JavaScript。该库比Linq.js快2-3倍,并且包含所有Linq方法的单元测试。也许您可以复习一下。

看一下underscore.js,它提供了许多类似于linq的功能。在示例中,您将使用map函数。

您可以尝试使用manipula实现所有C#LINQ方法并保存其语法的软件包:https :
//github.com/litichevskiydv/manipula

https://www.npmjs.com/package/manipula

您的示例selectedFruits.select(fruit=>fruit.id);
将通过以下方式实现:

Manipula.from(selectedFruits).select(fruit=>fruit.id);

Dinqyjs具有类似于linq的语法,并为诸如map和indexOf之类的功能提供了polyfills,并且是专门为在Javascript中处理数组而设计的。

看一看fluent,它支持LINQ所做的几乎所有事情,并且基于可迭代对象-因此它可与映射,生成器函数,数组以及所有可迭代对象一起使用。

最相似的C#Select模拟将是一个map函数。只需使用:

var ids = selectedFruits.map(fruit => fruit.id);

selectedFruits数组中选择所有ID

它不需要任何外部依赖关系,只需要纯JavaScript。您可以在map这里找到文档:https : //developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map

我是在回答问题的标题,而不是更具体的原始问题。

有了Javascript的新功能(例如迭代器,生成器函数和对象),诸如LINQ for Javascript之类的东西就成为可能。请注意,例如linq.js使用了一种完全不同的方法,即使用正则表达式,可能是为了克服当时对该语言缺乏支持的情况。

话虽如此,我已经为Javascript编写了LINQ库,您可以在https://github.com/Siderite/LInQer上找到它评论和讨论,网址https://siderite.dev/blog/linq-in-javascript-linqer

从以前的答案来看,只有Manipula才是Java的LINQ端口所期望的。

本文地址:http://javascript.askforanswer.com/dengxiaoyuclinq-selectdejavascript.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!