Stack Overflow на русском Asked by Zhihar on January 11, 2021
Подскажите как получше реализовать следующую задачу:
Есть массив элементов, которые содержат поля value
. Необходимо получить массив, содержащий массивы элементов у которых все поля начинаются с одинаковой буквы (одинакового символа).
Поскольку массив не большой и скорость не очень критична, то можно использовать и не очень оптимальные, зато понятные и компактные техники.
Делаю так:
// отсортировать входной массив
const sorted = this.props.data.sort((a, b) => a.value.localeCompare(b.value));
// получить список уникальных первых букв
const letters = sorted.map(obj => obj.value[0].toUpperCase()).sort().filter(function(item, pos, data) {
return !pos || item !== data[pos - 1];
});
// сформировать итоговый массив
const lists = letters.map(obj => sorted.filter(item => obj.localeCompare(item.value[0]) === 0));
(предложенный код конечно в 1 строчку записать можно было бы, но разбил для удобства)
Подскажите, можно ли более толково сделать?
Т.е.
Например мне очень не нравится как реализована уникальность букв в массиве – через
.filter(function(item, pos, data) {
return !pos || item !== data[pos - 1];
});
Может есть более правильный путь?
P.S.
входные данные
data = [
{value = "Иван", id = 11},
{value = "Игорь", id = 10},
{value = "Михаил", id = 18},
{value = "Максим", id = 21},
{value = "Петр Викторович", id = 110},
];
такое что ли?
const data = [
{value : "Иван", id : 11},
{value : "Игорь", id : 10},
{value : "Михаил", id : 18},
{value : "Максим", id : 21},
{value : "Петр Викторович", id : 110},
];
let group = data.reduce(function(acc,v){
let l = v.value[0].toUpperCase();
if(!acc[l]) acc[l] = [];
acc[l].push(v);
return acc;
}, { });
let result = Object.values(group);
console.log(result);
Correct answer by teran on January 11, 2021
const sorted = this.props.data.sort();
— эта строчка не делает то, что задумывалось: sort() по умолчанию сортирует по алфавиту, а у вас в data лежат объекты.
Можно еще так:
let data = [
{ value: "Иван", id: 11 },
{ value: "Игорь", id: 10 },
{ value: "Михаил", id: 18 },
{ value: "Максим", id: 21 },
{ value: "Петр Викторович", id: 110 },
];
data.sort((obj1, obj2) => obj1.value < obj2.value ? -1 : 1);
let curr_inner = [ data[0] ], result = [ curr_inner ];
for (let i = 1; i < data.length; i++) {
if (data[i].value[0] != data[i - 1].value[0]) { // Первые буквы не равны?
result.push(curr_inner = []); // Создается новый массив, добавляется в result
} // curr начинает ссылаться на этот массив, элементы продолжат добавляться туда
curr_inner.push(data[i]);
}
console.log(result);
И, например, завернуть это дело в функцию, оставив у неё вверху комментарий, описывающий, что она делает.
Answered by OPTIMUS PRIME on January 11, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP