C # LINQ Select와 동일한 Javascript


136

이 질문에 따라 여기 :

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

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

http://jsfiddle.net/NsCXJ/

과일 ID만으로 배열을 만드는 간단한 방법이 있습니까?

나는 C #을 사용하여 집에 더 많이 있습니다. selectedFruits.select(fruit=>fruit.id);

javascript / jquery와 비슷한 작업을 수행 할 수있는 방법 / 준비 기능이 있습니까? 아니면 가장 간단한 옵션은 목록을 반복하고 두 번째 배열을 만드는 것입니까? JSON으로 서버에 배열을 다시 게시하려고하므로 전송 된 데이터를 최소화하려고합니다.

답변:


227

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

다음은 함수 생성자와 객체 리터럴 속도를 비교 하는 jsperf 테스트 입니다. 전자를 사용하기로 결정한 경우 문자열을 올바르게 인용하십시오.

개인적으로 선호하는 것은 1-2 속성을 필터링 할 때 객체 리터럴 기반 솔루션을 사용하고 더 복잡한 필터링을 위해 콜백 함수를 전달하는 것입니다.

네이티브 객체 프로토 타입에 메소드를 추가 할 때 2 가지 일반적인 팁으로이 작업을 끝내겠습니다.

  1. 덮어 쓰기 전에 기존 방법이 있는지 확인하십시오. 예 :

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

  2. IE8 이하를 지원할 필요가없는 경우, Object.defineProperty 를 사용하여 메소드를 열거 할 수 없도록 정의하십시오 . 누군가 for..in가 배열에서 사용하면 (처음에는 잘못됨) 열거 가능한 속성도 반복합니다. 그냥 머리 위로.


1
@ChrisNevill 나는 당신이 모욕을당하는 경우에도 문자열 버전을 추가했습니다
Johan

@MUlferts 좋은 캐치, 업데이트 :). 요즘에는 이러한 종류의 작업에 lodash를 사용하는 것이 좋습니다. 위 코드와 동일한 인터페이스를 보여줍니다
Johan

녹아웃 return typeof item[property] === 'function' ? item[property]() === filter[property] : item[property] === filter[property];
Linus Caldwell

@LinusCaldwell 녹아웃을 사용한 지 오랜 시간이 지났지 만, return ko.unwrap(item[property]) === filter[property]어떻습니까?
Johan

글쎄, 나는 녹아웃에 대해 언급했지만 물론 이것은 필요한 매개 변수가없는 함수 인 모든 속성을 포괄합니다. 게다가 왜 아름다운 코드의 일반적인 스타일을 깨뜨릴 수 있습니까?
Linus Caldwell

33

답이 늦다는 것을 알고 있지만 나에게 유용했습니다! $.grep함수를 사용 하여 linq를 에뮬레이션 할 수 있습니다 where().

Linq :

var maleNames = people
.Where(p => p.Sex == "M")
.Select(p => p.Name)

자바 스크립트 :

// replace where  with $.grep
//         select with $.map
var maleNames = $.grep(people, function (p) { return p.Sex == 'M'; })
            .map(function (p) { return p.Name; });

그것이 내가 원하는 것입니다 .. 그러나 당신의 대답과 Enumerable. 사이에 더 좋은 것은 From (selectedFruits) .Select (function (fruit) {return fruit.id;});
Bharat

15

녹아웃을 사용하고 있기 때문에 녹아웃 유틸리티 기능 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;
});

자바 스크립트에서 LINQ와 같은 인터페이스를 원한다면 linq.js 와 같은 라이브러리를 사용 하여 많은 LINQ 메소드에 대한 멋진 인터페이스를 제공 할 수 있습니다 .

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

14

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/


매우 감사. ES6에 들어가서 편리합니다!
크리스 Nevill


4

일반 자바 스크립트에도 사용할 수있는 TsLinq.codeplex.com 아래에 TypeScript 용 Linq 라이브러리를 작성했습니다 . 이 라이브러리는 Linq.js보다 2-3 배 빠르며 모든 Linq 메소드에 대한 단위 테스트를 포함합니다. 어쩌면 당신은 그것을 검토 할 수 있습니다.




0

Dinqyjs 는 linq와 유사한 구문을 가지며 map 및 indexOf와 같은 함수에 대한 폴리 필을 제공하며 Javascript의 배열 작업을 위해 특별히 설계되었습니다.


0

유창한 것을 살펴보면 LINQ가 수행하는 거의 모든 것을 지원하고 반복 가능 항목을 기반으로하므로 맵, 생성기 함수, 배열 및 반복 가능한 모든 항목과 작동합니다.



-1

더 구체적인 원래 질문보다는 질문의 제목에 답하고 있습니다.

반복자 및 생성기 함수 및 객체와 같은 Javascript의 새로운 기능을 사용하면 LINQ for Javascript와 같은 것이 가능해집니다. 예를 들어 linq.js는 정규 표현식을 사용하는 완전히 다른 접근 방식을 사용하여 당시의 언어 지원 부족을 극복 할 수 있습니다.

그 말로 Javascript 용 LINQ 라이브러리를 작성했으며 https://github.com/Siderite/LInQer 에서 찾을 수 있습니다 . 에서 댓글 및 토론 https://siderite.dev/blog/linq-in-javascript-linqer .

이전 답변에서 Manipula 만 Javascript의 LINQ 포트에서 기대하는 것 같습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.