Я перебираю массив объектов, чтобы динамически генерировать HTML, отсортированный по одному или нескольким значениям, найденным в объектах.
Данные:
data = [ { value: "FirstValue", category: "FirstCategory" }, { value: "SecondValue", category: "FirstCategory" }, { value: "ThirdValue", category: "SecondCategory" }, { value: "FourthValue", category: "FirstCategory" }]
Мое решение начинается с создания пустого массива, перебирая объекты в данных и проверяя, содержит ли массив категорий объектную категорию.
Если категория в категориях, я нахожу HTML со значением категории, добавляю внутри необходимые значения.
Если категория не в категориях, я помещаю новую категорию в массив категорий, создаю новый HTML-div со значением категории внутри и добавляю HTML-div со значением объекта внутри этого вновь созданного div-категории.
categories = [];
for (var i = 0; i < data.length; i++) {
value = data[i][value]
category = data[i][category];
if (categories.includes(category)) {
console.info("Category already in array");
existingCatBlock = findHTMLWhereCatIsCat(category);
newHTMLBlockWithValue = newBlock(value);
existingCatBlock.append(newHTMLBlockWithValue);
}
else {
categories.push(category);
newCategoryBlock = newBlockWithCat(category);
newHTMLBlockWithValue = newBlock(value);
newCategoryBlock.append(newHTMLBlockWithValue);
mainHTMLContainer.append(newCategoryBlock);
}
}
Текущее решение выполняет свою работу, но, возможно, есть лучшие, более элегантные известные способы сделать это, особенно в случае, если было больше значений для сортировки.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В основном для удобства чтения я бы попробовал сначала манипулировать массивом, отсортировав его так, как вы хотите, а затем добавить все на экран.
Я бы сначала создал словарь из ваших данных, ключи которого были бы категориями, а значения были бы массивами со значениями ваших категорий. Array.reduce() можно использовать для его создания. Это дает следующий объект:
{
"FirstCategory": [
"FirstValue",
"SecondValue",
"FourthValue"
],
"SecondCategory": [
"ThirdValue"
]
}
Затем вы можете перебирать записи этого словаря, используя Object.entries(), Array.forEach() и Array.map(), чтобы построить каждую категорию, добавить ее дочерние элементы и вставить всю категорию в DOM.
Таким образом, вам не нужно отслеживать, какие категории уже существуют в DOM. Вам просто нужно вставить его один раз со всеми его дочерними элементами благодаря промежуточному отображению категорий в значения.
const data = [
{ value: "FirstValue", category: "FirstCategory" },
{ value: "SecondValue", category: "FirstCategory" },
{ value: "ThirdValue", category: "SecondCategory" },
{ value: "FourthValue", category: "FirstCategory" }
];
const dataByCategories = data.reduce((acc, { value, category }) => {
acc[category] = [...(acc[category] || []), value];
return acc;
}, {});
const mainHTMLContainer = document.querySelector('#main');
Object.entries(dataByCategories).forEach(([category, values]) => {
const valuesHTML = values.map(newBlock).join('');
const categoryBlock = newBlockWithCat(category, valuesHTML);
// A single appendChild is done for each category
mainHTMLContainer.appendChild(categoryBlock);
});
function newBlock(value) {
return `<div class = "value">html for ${value}</div>`;
}
function newBlockWithCat(category, values) {
const div = document.createElement('div');
div.classList.add('category');
div.innerHTML = values;
return div;
}.value {
padding: 2px;
}
.category {
display: inline-block;
border: 1px solid black;
width: 150px;
margin: 5px;
}<div id = "main">
</div>