Создать дерево из плоского массива объектов, родительский элемент которого не указан ключом - PullRequest
0 голосов
/ 12 апреля 2020

У меня есть плоский массив объектов, из которых я пытаюсь сгенерировать дерево. Первоначально данные не сортируются и представляют собой данные категории продуктов, полученные из API онлайнового рынка, который состоит из около 5000 наименований.

Небольшая часть данных выглядит следующим образом.

        "@deepest": "false",
        "categoryCode": "1",
        "categoryName": "Pet products"
    },
    {
        "@deepest": "false",
        "categoryCode": "1b",
        "categoryName": "Bird"
    },
    {
        "@deepest": "true",
        "categoryCode": "1ba",
        "categoryName": "Bird Accessories"
    },
    {
        "@deepest": "true",
        "categoryCode": "1bb",
        "categoryName": "Bird care products"
    },
    {
        "@deepest": "true",
        "categoryCode": "1bc",
        "categoryName": "Bird Cage"
    }
 ]

Кажется, что тренд внутри данных идет в виде categoryCode с одним символом, являющимся верхними категориями. Глядя на частичные данные, можно увидеть, что categoryCode 1 - что составляет Pet Products - имеет дочерний элемент с categoryCode 1b и детей 1bb и 1b c и т. Д.

Итак, исходя из этого отношения, я хочу создать дерево объектов выглядит следующим образом:

[
  {
    "@deepest": "false",
    "categoryCode": "1",
    "categoryName": "Pet products",
    "children": [
      {
        "@deepest": "false",
        "categoryCode": "1b",
        "categoryName": "Bird",
        "children": [
          {
            "@deepest": "true",
            "categoryCode": "1ba",
            "categoryName": "Bird Accessories"
          },
          {
            "@deepest": "true",
            "categoryCode": "1bb",
            "categoryName": "Bird care products"
          },
          {
            "@deepest": "true",
            "categoryCode": "1bc",
            "categoryName": "Bird Cage"
          }
        ]
      }
    ]
  }
]


Каков наиболее оптимальный способ достижения желаемого результата без проблем с производительностью?

Примечание: было предпринято несколько попыток без solid результата, но разочарования.

Ответы [ 2 ]

1 голос
/ 12 апреля 2020

Чтобы иметь строки, отражающие их отношение, вы можете собрать все categoryCode и их объекты и получить отношение longes / closest и построить дерево.

Этот подход работает и для более длинных кодов, чем один символ .

var data = [{ "@deepest": "false", categoryCode: "1", categoryName: "Pet products" }, { "@deepest": "false", categoryCode: "1b", categoryName: "Bird" }, { "@deepest": "true", categoryCode: "1ba", categoryName: "Bird Accessories" }, { "@deepest": "true", categoryCode: "1bb", categoryName: "Bird care products Bakım Ürünleri" }, { "@deepest": "true", categoryCode: "1bc", categoryName: "Bird Cage" }],
    tree = function (array) {
        var t = { '': { children: [] } };
        array.forEach(o => t[o.categoryCode] = o);
        Object
            .keys(t)
            .sort((a, b) => a.length - b.length)
            .forEach((k, i, a) => {
                let j = i;
                while (j--) if (k.startsWith(a[j])) {
                    (t[a[j]].children = t[a[j]].children || []).push(t[k]);
                    break;
                };
            });
        return t[''].children;
    }(data, '');

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 голос
/ 12 апреля 2020

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

const data = [{"@deepest":"false","categoryCode":"1","categoryName":"Pet products"},{"@deepest":"false","categoryCode":"1b","categoryName":"Bird"},{"@deepest":"true","categoryCode":"1ba","categoryName":"Bird Accessories"},{"@deepest":"true","categoryCode":"1bb","categoryName":"Bird care products Bakım Ürünleri"},{"@deepest":"true","categoryCode":"1bc","categoryName":"Bird Cage"}]

const { value: result } = data.reduce((a, o) => {
  return o.categoryCode.split('').reduce((r, e) => {
    if(!r[e]) {
      const obj = { ...o  }
      
      r[e] = { value: [] }
      
      if(o['@deepest'] !== 'true') {
      	obj.children = r[e].value
      }
      
      r.value.push(obj)
    }
    
    return r[e]
  }, a), a
}, { value: [] })

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