Javascript nested filters in Array of arrays
You could use a hash table for the selectedID and use it for fast filtering.
var full_list = [{ "pid": 1, "items": [{ "item_id": '9' }, { "item_id": '10' }, { "item_id": '12' }] }, { "pid": 2, "items": [{ "item_id": '33' }, { "item_id": '22' }, { "item_id": '65' }] }],
tmp_list,
selectedIDs = ['1', '9', '45'],
selected = Object.create(null);
selectedIDs.forEach(function (a) {
selected[a] = true;
});
tmp_list = full_list.filter(function (a) {
return !a.items.some(function (b) {
return selected[b.item_id];
});
});
console.log(tmp_list);
ES6
var full_list = [{ "pid": 1, "items": [{ "item_id": '9' }, { "item_id": '10' }, { "item_id": '12' }] }, { "pid": 2, "items": [{ "item_id": '33' }, { "item_id": '22' }, { "item_id": '65' }] }],
tmp_list,
selectedIDs = ['1', '9', '45'],
selected = Object.create(null);
selectedIDs.forEach(a => selected[a] = true);
tmp_list = full_list.filter(a => !a.items.some(b=> selected[b.item_id]));
console.log(tmp_list);
First of all, this line in your question is wrong
var selectedIDs = {'1', '9', '45', ....};
You cannot declare arrays using {}
. Instead use []
For your problem you can use a pure functional approach using Array#filter and Array#some methods to get your desired result as below:
var full_list = [
{
"pid": 1,
"items":[
{"item_id": '9'},
{"item_id": '10'},
{"item_id": '12'}
]
},
{
"pid": 2,
"items":[
{"item_id": '33'},
{"item_id": '22'},
{"item_id": '67'}
]
},
{
"pid": 9,
"items":[
{"item_id": '33'},
{"item_id": '22'},
{"item_id": '65'}
]
},
{
"pid": 7,
"items":[
{"item_id": '7'},
{"item_id": '22'},
{"item_id": '65'}
]
}
];
var tmp_list = [
{
"pid": 2,
"items":[
{"item_id": '7'},
{"item_id": '22'},
{"item_id": '65'}
]
}
];
function filterResult (selectedItems) {
return full_list.filter(function (process) {
return process.items.some(function(item){
return selectedItems.indexOf(item.item_id) > -1;
});
});
}
var selectedItems = ['9', '7', '22', '10'];
tmp_list = tmp_list.concat(filterResult(selectedItems))
console.log(tmp_list);
function flattenResults(list, selections) {
return list.reduce(function (accumulator, current) {
var res = current.items.filter(function(item){
return (selections.indexOf(item.item_id) > -1
&& checkIfAlreadyExist());
function checkIfAlreadyExist () {
return accumulator.every(function (k) {
return k.item_id !== item.item_id;
});
}
});
return accumulator.concat(res);
}, []);
}
console.log(flattenResults(full_list, selectedItems));
You may do like this;
var full_list = [
{
"pid": 1,
"items":[
{"item_id": '9'},
{"item_id": '10'},
{"item_id": '12'}
]
},
{
"pid": 2,
"items":[
{"item_id": '33'},
{"item_id": '22'},
{"item_id": '65'}
]
}
],
selectedIDs = ['1', '9', '45'],
tempList = [];
tempList.push(full_list.filter(f => f.items.some(o => selectedIDs.includes(o.item_id))));
console.log(tempList);