Подтвердить что ты не робот

Underscore.js фильтрует массив объектов на основе другого

Я пытаюсь отфильтровать массив объектов на основе другого. Общий идентификатор свойства id. Я не уверен, что фильтр + каждый - лучший способ сделать это или уменьшить карту. Во всяком случае, ниже код не работает, поскольку out - пустой список.

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);
4b9b3361

Ответ 1

Просто создайте "набор" допустимых идентификаторов и используйте "set" для фильтрации:

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 выполняется быстро, оно в n * амортизируется O (1), то есть O (n). То же самое относится к фильтрации.

Если вы используете each(…) во внутреннем цикле, у вас будет O (n²). Для больших наборов данных это будет очень медленным. Кроме того, дополнительное вложение делает код более трудным для чтения/понимания с первого взгляда.

Смотрите, что код отключен в действии: http://jsfiddle.net/SMtX5/

Ответ 2

вы можете использовать _.find для фильтрации:

_.filter(aaa, function(a){
    return _.find(bbb, function(b){
        return b.id === a.id;
    });
});

Ответ 3

Вы можете использовать _.some(list, [iterator], [context]).

Возвращает true, если какое-либо из значений в списке проходит тест истины итератора.

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

Вот jsfiddle. http://jsfiddle.net/h98ej/

Ответ 4

bbb = bbb.map(_ => _.id) && aaa.filter(_ => bbb.indexOf( _.id ) > -1)

Вам просто нужны чистые функции массива JS для этого, предполагая ваш прецедент.