2013-02-27 2 views
20

다른 객체를 기반으로 객체 배열을 필터링하려고합니다. 공통 속성 id는 id입니다. 필자는 필터 + 또는 맵 축소가 가장 좋은 방법인지 잘 모르겠습니다. 어쨌든 out은 빈 목록이므로 코드 아래에서 작동하지 않습니다.underscore.js 다른 객체를 기반으로 한 객체 배열을 필터링합니다.

var aaa = [ 
    {name: "AAA", id: 845}, 
    {name: "BBB", id: 839}, 
    {name: "CCC", id: 854} 
]; 
var bbb = [ 
    {id: 839}, 
    {id: 854} 
]; 

var out = _.filter(aaa, function(val){ 
    return _.each(this, function(val2){ 
     return val['id'] === val2['id'] 
    }); 
}, bbb); 

답변

37

는 그냥 유효한 ID의 "설정"작성하고 필터링 할 "설정"는 사용이 n 개의 *에있어,

var aaa = [ 
    {name: "AAA", id: 845}, 
    {name: "BBB", id: 839}, 
    {name: "CCC", id: 854} 
]; 
var bbb = [ 
    {id: 839}, 
    {id: 854} 
]; 

var ids = {}; 
_.each(bbb, function (bb) { ids[bb.id] = true; }); 

var out = _.filter(aaa, function (val) { 
    return ids[val.id]; 
}, bbb); 

ids가 빠른 충전을 amortized O (1) 즉 O (n). 필터링에도 동일하게 적용됩니다.

each(…)을 내부 루프에 사용하면 O (n²)가됩니다. 더 큰 데이터 세트의 경우 이것은 매우 느려집니다. 또한 추가적인 네 스팅 (nesting)은 코드를 한눈에 읽기/이해하기가 더 어렵게 만듭니다. 당신은 _.some(list, [iterator], [context])을 사용할 수 있습니다 http://jsfiddle.net/SMtX5/

+1

은 설명 및 추론보다 큼. – bsr

2

:

행동에 냈다 그 코드를 참조하십시오.

그것은 목록의 값 중 하나가 반복자 진실 시험을 통과하면 사실를 반환합니다.

var out = _.filter(aaa, function(val){ 
    return _.some(this,function(val2){ 
     return val2['id'] === val['id']; 
    }); 
}, bbb); 

여기에 jsfiddle이 있습니다. http://jsfiddle.net/h98ej/

+0

허용 된 답변을 기반으로,이 루틴이 더 빨리 받아 들여집니다. –

15

필터링 _.find를 사용할 수 있습니다

_.filter(aaa, function(a){ 
    return _.find(bbb, function(b){ 
     return b.id === a.id; 
    }); 
}); 
1
bbb = bbb.map(_ => _.id) && aaa.filter(_ => bbb.indexOf(_.id) > -1) 

당신은 단지 할 순수한 JS 배열 기능을 필요로하는 사용 사례를 가정.

관련 문제