Есть ли лучший способ сортировки массива объектов для динамического создания HTML-элементов, разделенных по значению? - PullRequest
0 голосов
/ 19 февраля 2019

Я перебираю массив объектов, чтобы динамически генерировать 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);
    }
}

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

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Я бы сначала создал словарь из ваших данных, ключи которого были бы категориями, а значения были бы массивами со значениями ваших категорий.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>
0 голосов
/ 19 февраля 2019

В основном для удобства чтения, я сначала попытался бы манипулировать массивом, сортировать его так, как вы хотите, а затем добавлять все на экран.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...