#javascript #ecmascript-6
Вопрос:
Мне нужно извлечь из carriers
кода элементы, присутствующие в active
массиве:
const carriers = [
{ id: 0, code: "gls" },
{ id: 1, code: "tnt" },
{ id: 2, code: "fedex" },
{ id: 3, code: "ups" },
{ id: 4, code: "postnl" },
];
const active = [0, 2, 3];
const active_code = [];
let result = carriers.filter((c) => active.includes(Number(c.id)));
console.log(result);
result.forEach((item) => {
active_code.push(item.code);
});
console.log(active_code);
Ожидаемый результат:
["gls", "fedex", "ups"]
Приведенный выше код работает, но я хотел бы узнать, есть ли лучший/более простой/элегантный способ получить тот же результат?
Спасибо
Ответ №1:
Для начала можно настроить его, сопоставив вместо создания пустого массива и нажав на него.
carriers.filter(i=>active.includes( i.id)).map(i=>i.code)
Комментарии:
1. Я думаю, что это не лучшее решение, но, ИМХО, его легче всего понять тем, кто столкнется с той же проблемой с ограниченными навыками, что и я
Ответ №2:
Сопоставьте active
массив .find
, указав соответствующую несущую.
const carriers = [
{"id":0,"code":"gls"},
{"id":1,"code":"tnt"},
{"id":2,"code":"fedex"},
{"id":3,"code":"ups"},
{"id":4,"code":"postnl"}
];
const active = [0,2,3];
const result = active.map(id => carriers.find(c => c.id === id).code);
console.log(result);
Для меньшей вычислительной сложности сначала превратите его carriers
в структуру, индексируемую идентификатором.
const carriers = [
{"id":0,"code":"gls"},
{"id":1,"code":"tnt"},
{"id":2,"code":"fedex"},
{"id":3,"code":"ups"},
{"id":4,"code":"postnl"}
];
const active = [0,2,3];
const carriersById = Object.fromEntries(
carriers.map(c => [c.id, c])
);
const result = active.map(id => carriersById[id].code);
console.log(result);
Комментарии:
1. оба варианта являются идеальным решением
Ответ №3:
1) Вы можете достичь результата с помощью карты.
const carriers = [
{ id: 0, code: "gls" },
{ id: 1, code: "tnt" },
{ id: 2, code: "fedex" },
{ id: 3, code: "ups" },
{ id: 4, code: "postnl" },
];
const active = [0, 2, 3];
const map = new Map(carriers.map(({ id, code }) => [id, code]));
const active_code = active.map((id) => map.get(id));
console.log(active_code);
2) Вы также можете получить результат с помощью набора
const carriers = [
{ id: 0, code: "gls" },
{ id: 1, code: "tnt" },
{ id: 2, code: "fedex" },
{ id: 3, code: "ups" },
{ id: 4, code: "postnl" },
];
const active = [0, 2, 3];
const set = new Set(active);
const active_code = carriers
.filter((o) => set.has(o.id))
.map(({ code }) => code);
console.log(active_code);
Ответ №4:
Я бы сопоставил carriers
данные active_code
напрямую.
Вы также можете создать active_ids
объект, чтобы избежать вызова includes
для каждой записи.
const carriers = [
{ "id": 0, "code": "gls" },
{ "id": 1, "code": "tnt" },
{ "id": 2, "code": "fedex" },
{ "id": 3, "code": "ups" },
{ "id": 4, "code": "postnl" }
];
const active = [0, 2, 3];
const active_ids = Object.fromEntries(active.map(i => [i, true]));
let active_code = carriers
//.filter(c => active.includes(c.id))
.filter(c => active_ids[c.id]) // faster if many items?
.map(c => c.code)
console.log(active_code);
// expected ["gls", "fedex", "ups"]
console.assert(active_code[0] === "gls")
console.assert(active_code[1] === "fedex")
console.assert(active_code[2] === "ups")