2017-01-22 8 views
1

У меня естьфильтрация в json с помощью id и возврат массива; карта без неопределенных

let list = { 
    1: { name: "someone1" }, 
    5: { name: "someone5" }, 
    7: { name: "someone7" }, 
    8: { name: "someone8" } 
}; 

и я хочу, чтобы фильтровать [1,5,42]

[ 
{ name: "someone1" }, 
{ name: "someone5" } 
] 

Я попытался

Object.keys(list).map(key=> {if([1,5,42].includes(key)) return list[key]}); 

[ 
{ name: "someone1" }, 
{ name: "someone5"}, 
undefined, 
undefined 
] 

PS: Когда мой список был массив json, я использовал list.filter(person => [1,5].includes(person.id)). Затем я переключился на ключевую модель id, поэтому я могу использовать liat[id], что намного быстрее, чем list.filter для одного элемента.

ответ

3

Вы можете напрямую перебрать фильтр и взять объект.

let list = { 1: { name: "someone1" }, 5: { name: "someone5" }, 7: { name: "someone7" }, 8: { name: "someone8" } }, 
 
    filter = [1, 5], 
 
    result = filter.map(k => list[k]); 
 

 
console.log(result);

Вам нужен другой подход, если фильтр содержит строки, которые не являются ключами от объекта.

let list = { 1: { name: "someone1" }, 5: { name: "someone5" }, 7: { name: "someone7" }, 8: { name: "someone8" } }, 
 
    filter = [1, 5, 42], 
 
    result = filter.reduce((r, k) => r.concat(list[k] || []), []); 
 

 
console.log(result);

в два этапа раствора со значениями отображения объекта и фильтрации с Boolean для truthy элементов.

let list = { 1: { name: "someone1" }, 5: { name: "someone5" }, 7: { name: "someone7" }, 8: { name: "someone8" } }, 
 
    filter = [1, 5, 42], 
 
    result = filter.map(key => list[key]).filter(Boolean); 
 

 
console.log(result);

+0

Вероятно, самым простым решением –

+0

я специально хотел 42 часть. .! сделал редактирование в вопросе –

+0

Итак, трюк заключается в том, что, поскольку карта всегда возвращает что-то, вы использовали сокращение и нажали на массив результатов, только если его не определено ...? –

0

let list = { 
 
    1: { name: "someone1" }, 
 
    5: { name: "someone5" }, 
 
    7: { name: "someone7" }, 
 
    8: { name: "someone8" } 
 
}; 
 
function filter(ids, list){ 
 
    var ret = []; 
 
    for(var i in ids){ 
 
    var id = ids[i]; 
 
    ret.push(list[id]); 
 
    } 
 
    return ret; 
 
} 
 
var filtered = filter([1,5], list); 
 
console.log(filtered);

это решение предполагает, что вы спросите только для существующих ключей.

+0

спасибо, но я сделал редактирование на вопрос: мне нужно устранить 'undefined', если их нет –

1

Вы можете использовать назначение деструктурирующие

let res = []; 
({1:res[res.length], 5:res[res.length]} = list); 

let list = { 
 
    1: { name: "someone1" }, 
 
    5: { name: "someone5" }, 
 
    7: { name: "someone7" }, 
 
    8: { name: "someone8" } 
 
}; 
 

 
let [keys, res] = [["1", "5"], []]; 
 

 
for (let key of keys) {({[key]:res[res.length]} = list)} 
 

 
console.log(res);

+0

Можете ли вы объяснить, как это работает? '({1: res [res.length], 5: res [res.length]} = list);' и что происходит, когда у меня есть 42 в ключах (несуществующий ключ)? –

+0

@ZekeDran '{1: res [res.length]}' получает свойство '" 1 "от объекта и присваивает значение' res [res.length] '. В первом примере ключи свойств явно передаются. В цикле 'for..of' текущий элемент массива является вычисленным именем свойства внутри' [] '. Результатом передачи '42' или' "42" 'будет элемент' undefined' в результирующем массиве. Какова цель передачи несуществующего свойства в массив? – guest271314

+0

Список выбирается отдельно, а массив ключей выбирается отдельно от сервера: ключи на первом месте! Поскольку я использую хранилище redux, список будет {} изначально, что делает ключи недействительными в то время и не говоря уже о том, что пара неопределенных внутри массива свертывает все приложение –

0

Однострочные раствор:

[1,5,42].map(key => list[key]).filter(el => el) 
// if(el != null) return true shortened as el => el 

Нины Scholz просто один лайнер: [1,5,42].reduce((r, k) => r.concat(list[k] || []), []); отличается тем, что он проверяет перед добавлением его в массив, а выше один удаляет undefined с после создания массива.

Еще один возможный один лайнер будет:

["1","5","42"].filter(key => Object.keys(list).includes(key)).map(key => list[key]) 
//This one removes the invalid keys and then build an array without `undefined`s 

Отрывок:

let list = { 
 
    1: { name: "someone1" }, 
 
    5: { name: "someone5" }, 
 
    7: { name: "someone7" }, 
 
    8: { name: "someone8" } 
 
}; 
 

 
console.log([1,5,42].map(key => list[key]).filter(el => el)); 
 

 
console.log(["1","5","42"].filter(key => Object.keys(list).includes(key)).map(key => list[key]));

+0

Требование «однострочный» не появляется в оригинальном вопросе. Как «javascript» в этом ответе отличается от 'javascript' на @NinaScholz? Вы сравнили время, в течение которого 'javascript' при каждом ответе берется для завершения процесса? Не ясно из оригинального вопроса, каково фактическое требование? – guest271314

+0

'Один вкладыш' не является первоначальным требованием; ** Ваш ответ на самом деле является ответом на мой вопрос, и я могу использовать его **; И это просто другие возможности, о которых я думал ... –