2013-06-22 6 views
47

속성 값 배열을 사용하여 컬렉션을 필터링하고 싶습니다. ID의 배열이 주어지면 ID가 일치하는 객체를 반환합니다. lodash/underscore을 사용하는 바로 가기 방법이 있습니까?lodash 값 배열을 사용하는 필터 모음

var collections = [{ id: 1, name: 'xyz' }, 
        { id: 2, name: 'ds' }, 
        { id: 3, name: 'rtrt' }, 
        { id: 4, name: 'nhf' }, 
        { id: 5, name: 'qwe' }]; 
var ids = [1,3,4]; 

// This works, but any better way? 

var filtered = _.select(collections, function(c){  
    return ids.indexOf(c.id) != -1 
}); 
+0

아니요.그러나 Arrays 프로토 타입의'filter()'메소드를 직접 다룰 수있다. 더 깨끗하게 보입니다. – gustavohenke

답변

58

당신이 패턴의 종류를 많이 사용하는 거라면, 당신은 다음과 같은,하지만, 그것은 원래의 코드보다 fundementally 다른 아무것도하지 않는 믹스 인을 만들 수 있습니다. 개발자가 쉽게 사용할 수있게 해줍니다.

_.mixin({ 
    'findByValues': function(collection, property, values) { 
    return _.filter(collection, function(item) { 
     return _.contains(values, item[property]); 
    }); 
    } 
}); 

다음과 같이 사용할 수 있습니다.

var collections = [ 
    {id: 1, name: 'xyz'}, 
    {id: 2, name: 'ds'}, 
    {id: 3, name: 'rtrt'}, 
    {id: 4, name: 'nhf'}, 
    {id: 5, name: 'qwe'} 
]; 

var filtered = _.findByValues(collections, "id", [1,3,4]); 

업데이트 -이 위의 대답은 과거와 어설픈입니다. 훨씬 더 우아한 해결책을 위해서는 answer from Adam Boduch을 사용하십시오.

_(collections) 
    .keyBy('id') // or .indexBy() if using lodash 3.x 
    .at(ids) 
    .value(); 
+0

keyBy에 대한 끝 인용문이 없습니다. 나는 맞을 것이지만, 그래서 하나의 문자를 추가 할 수는 없다.) –

6

나는 jessegavin's 대답을 좋아하지만, 나는 깊은 건물 일치에 lodash-deep을 사용하여 확대했다.

var posts = [{ term: { name: 'A', process: '123A' } }, 
      { term: { name: 'B', process: '123B' } }, 
      { term: { name: 'C', process: '123C' } }]; 

var result = _.filterByValues(posts, 'term.process', ['123A', '123C']); 
// results in objects A and C to be returned 

jsFiddle

_.mixin({ 
    'filterByValues': function(collection, key, values) { 
     return _.filter(collection, function(o) { 
      return _.contains(values, resolveKey(o, key)); 
     }); 
    } 
}); 

function resolveKey(obj, key) { 
    return (typeof key == 'function') ? key(obj) : _.deepGet(obj, key); 
} 

당신이 lodash 깊은 신뢰하지 않거나 당신이 여기보다 방어하고 강력한 버전입니다, 이름에 점을 속성에 대한 지원을 원하는 경우 :

function resolveKey(obj, key) { 
    if (obj == null || key == null) { 
     return undefined; 
    } 
    var resolved = undefined; 
    if (typeof key == 'function') { 
     resolved = key(obj); 
    } else if (typeof key == 'string') { 
     resolved = obj[key]; 
     if (resolved == null && key.indexOf(".") != -1) { 
      resolved = _.deepGet(obj, key); 
     } 
    } 
    return resolved; 
} 
+3

lodash'get'은 기본적으로 깊기 때문에'_.get (object, 'a [0] .b.c')와 같은 것을 할 수있다. ;'. @jessegavin이 딥 프로퍼티를 지원하기 위해해야 ​​할 일은'item (property)'를'_.get (item, property)'로 바꾸는 것뿐입니다. [lodash 문서] (https://lodash.com/docs#get)를 참조하십시오. – danbars

34

indexBy()at()을 사용하는 간결한 로다시 솔루션.

_(collections) 
    .indexBy('id') 
    .at(ids) 
    .value(); 
+5

이 솔루션의이 진부함은 훌륭합니다. 그리고 Lodash 4 사용자는'indexBy'를'keyBy'로 대체하여 기능을 계속 유지할 수 있습니다. –

+2

'collections'가'ids'와 일치하는 어떤 객체도 포함하지 않으면, 그것은 하나의 원소가 정의되지 않은 배열을 반환하는 것처럼 보입니다. '[undefined']. 이것은'someArray.length'에 대한 나의 테스트에 실패 했으므로'.filter()' '_ (collections) .keyBy ('id'). at (ids) .filter(). value();'를 추가했습니다. – steezeburger

12

우리는 또한 나는이 답변의 대부분은 오래된 또는 Lodash 문서에 나열되지 않은 보조 기능을 포함 발견이

var collections = [{ id: 1, name: 'xyz' }, 
      { id: 2, name: 'ds' }, 
      { id: 3, name: 'rtrt' }, 
      { id: 4, name: 'nhf' }, 
      { id: 5, name: 'qwe' }]; 



     var filtered_ids = _.filter(collections, function(p){ 
      return _.includes([1,3,4], p.id); 
     }); 

     console.log(filtered_ids); 
0

처럼 필터링 할 수 있습니다. 허용 된 답변에는 더 이상 사용되지 않는 기능 _.contains이 포함되어 있으며 업데이트해야합니다.

여기 내 ES6 답변입니다.

Lodash v4.17.4

_.mixin({ 
    filterByValues: (c, k, v) => _.filter(
     c, o => _.indexOf(v, o[ k ]) !== -1 
    ) 
}); 

을 기반으로하고 다음과 같은 호출 : '비 고유 한 값을 필터링하고 싶었 기 때문에

_.filterByValues(
    [ 
     { 
      name: 'StackOverflow' 
     }, 
     { 
      name: 'ServerFault' 
     }, 
     { 
      name: 'AskDifferent' 
     } 
    ], 
    'name', 
    [ 'StackOverflow', 'ServerFault' ] 
); 

// => [ { name: 'StackOverflow' }, { name: 'ServerFault' } ] 
0

이 대답은 나를 위해 작동하지 않았다. keyBygroupBy으로 변경하면 다음과 같이 처리 할 수 ​​있습니다.

_(collections) 
    .groupBy(attribute) 
    .pick(possibleValues) 
    .values() 
    .flatten() 
    .value(); 

내 최초 사용 일을 드롭했다, 그래서 나는 omitpick을 전환했다.

감사의 말은 Adam Boduch입니다.