我正在通过一系列对象循环,以动态生成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.log("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);
}
}
当前的解决方案可以完成工作,但是也许有更好,更优雅的已知方法可以做到这一点,尤其是在情况下,还有更多的价值。
主要是为了可读性,我将尝试先操纵数组,以您想要的方式对其进行排序,然后在屏幕上添加所有内容。
我将首先从您的数据中创建一个字典,其键将是类别,并且值将是带有类别值的数组。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>