IT박스

C # LINQ Select와 동일한 Javascript

itboxs 2020. 7. 12. 10:21
반응형

C # LINQ Select와 동일한 Javascript


이 질문에 따라 여기 :

확인란 목록과 함께 녹아웃에서 체크 된 바인딩을 사용하면 모든 확인란이 선택됩니다.

배열에서 선택할 수있는 녹아웃을 사용하여 확인란을 만들었습니다. 위의 게시물에서 가져온 작업 바이올린 :

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 메소드를 사용하는 것이 좋습니다.

어떤 이유로 다른 것을 선호하는 경우 이전 브라우저 지원을 위해 항상 폴리 필을 추가 ​​할 수 있습니다.

언제든지 배열 프로토 타입에 사용자 정의 메소드를 추가 할 수 있습니다.

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/

최신 정보:

이것이 인기있는 답변이되었으므로 비슷한 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;
};

용법:

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 test to compare the function constructor vs object literal speed. If you decide to use the former, keep in mind to quote strings correctly.

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.

I'll end this with 2 general tips when adding methods to native object prototypes:

  1. Check for occurrence of existing methods before overwriting e.g.:

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

  2. If you don't need to support IE8 and below, define the methods using Object.defineProperty to 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.


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().

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

Since you're using knockout, you should consider using the knockout utility function arrayMap() and it's other array utility functions.

Here's a listing of array utility functions and their equivalent LINQ methods:

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.js which offers a nice interface to many of the LINQ methods.

var mapped = Enumerable.From(selectedFruits)
    .Select("$.id") // 1 of 3 different ways to specify a selector function
    .ToArray();

The ES6 way:

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/


You can also try linq.js

In linq.js your

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

will be

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

I have build a Linq library for TypeScript under TsLinq.codeplex.com that 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.


Take a peek at underscore.js which provides many linq like functions. In the example you give you would use the map function.


You can try manipula package, which implement all of C# LINQ methods and save its syntax: https://github.com/litichevskiydv/manipula

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

Your example selectedFruits.select(fruit=>fruit.id); will be implemented with manipula as

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

Dinqyjs has a linq-like syntax and provides polyfills for functions like map and indexOf, and has been designed specifically for working with arrays in Javascript.

참고URL : https://stackoverflow.com/questions/18936774/javascript-equivalent-to-c-sharp-linq-select

반응형