JavaScript (рекурсия) Как из одного массива (каталог) сделать другой (дерево)?

Как сделать с 1 уровнем понятно, а как сделать рекурсию, чтоб неограниченные вложения были не понимаю
f= это уровень вложенности получается, справа налево

name=Tel3,f=Galaxy,f=Samsung,g=tovarov,g=catalog
name=Tel2,f=Samsung,g=tovarov,g=catalog

Samsung -> Galaxy -> Tel3
Samsung -> Tel2


На входе
[
  {
    "path": "name=Tel6,g=tovarov,g=catalog",
    "id": "6000",
    "name": "Tel6"
  },
  {
    "path": "name=Tel1,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
    "id": "1000",
    "name": "Tel1"
  },
  {
    "path": "name=Tel2,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
    "id": "2000",
    "name": "Tel2"
  },
  {
    "path": "name=Tel3,f=Galaxy,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
    "id": "3000",
    "name": "Tel3"
  },
  {
    "path": "name=Tel4,f=A,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
    "id": "4000",
    "name": "Tel4"
  },
  {
    "path": "name=Tel5,f=A,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
    "id": "5000",
    "name": "Tel5"
  }
  // ...
]


а на выходе хочу получить, для компонента построение дерева
[
  {
    "label": "Tel6",
    "id": "6000"
  },
  {
    "label": "Samsung",
    "id": "f=Samsung,g=tovarov,g=catalog", // Или может что угодно уникальное, если он имеет "children"
    "children": [
      {
        "label": "Tel1",
        "id": "1000" // Важное
      },
      {
        "label": "Tel2",
        "id": "2000" // Важное
      },
      {
        "label": "Galaxy",
        "id": "f=Galaxy,f=Samsung,g=tovarov,g=catalog", // Или может что угодно уникальное, если он имеет "children"
        "children": [
          {
            "label": "Tel3",
            "id": "3000" // Важное
          }
        ]
      },
      {
        "label": "A",
        "id": "f=A,f=Samsung,g=tovarov,g=catalog", // Или может что угодно уникальное, если он имеет "children"
        "children": [
          {
            "label": "Tel4",
            "id": "4000" // Важное
          },
          {
            "label": "Tel5",
            "id": "5000" // Важное
          }
        ]
      }
    ]
  },
  // ...
]
  • Вопрос задан
  • 127 просмотров
Пригласить эксперта
Ответы на вопрос 2
@Azperin
Дилетант
Прогоняешь циклом первый массив и заполняешь другой по условиям которые тебе нужны. Да и во втором массиве я массива то не вижу, там же 1 элемент, поэтому проще его опустить
var sourceArr = [...];
var obj = {};
sourceArr.forEach(x => {
  if(x[prop]) // парсиш ипроводиш нужные операции с объектом
  // тотже x.path просто сплитиш по запятой и делаешь внутренний цикл с проверкой obj.hasOwnProperty
  obj[prop] = x[prop] 
})
Ответ написан
bingo347
@bingo347
Бородатый программер
function parsePath(path) {
  return path.split(',').reduce((acc, item) => {
    const [key, value] = item.split('=');
    switch(key) {
    case 'name':
      acc.name = value;
      break;
    case 'f':
    case 'g':
      acc[key].push(value);
      break;
    }
    return acc;
  }, {
    name: '',
    f: [],
    g: []
  });
}

function normalizeTree(tree) {
  return Object.keys(tree).map(label => {
    const item = tree[label];
    if(item.id) { return item; }
    const children = normalizeTree(item);
    const id = `[${children.map(({id}) => id).join(',')}]`;
    return {id, label, children};
  });
}

function reduceToTree(data) {
  return normalizeTree(data.reduce((acc, {path, id}) => {
    const {name, f, g} = parsePath(path);
    const target = f.reverse().concat(name).reduce((target, label) => {
      return target[label] || (target[label] = {});
    }, acc);
    target.id = id;
    target.label = name;
    target.g = g;
    return acc;
  }, {}));
}

console.log(reduceToTree([
  {
    "path": "name=Tel6,g=tovarov,g=catalog",
    "id": "6000",
    "name": "Tel6"
  },
  {
    "path": "name=Tel1,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
    "id": "1000",
    "name": "Tel1"
  },
  {
    "path": "name=Tel2,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
    "id": "2000",
    "name": "Tel2"
  },
  {
    "path": "name=Tel3,f=Galaxy,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
    "id": "3000",
    "name": "Tel3"
  },
  {
    "path": "name=Tel4,f=A,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
    "id": "4000",
    "name": "Tel4"
  },
  {
    "path": "name=Tel5,f=A,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
    "id": "5000",
    "name": "Tel5"
  }
  // ...
]));
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Александрия Москва
от 200 000 до 250 000 руб.
Foodtronics Москва
от 100 000 до 200 000 руб.
Алгоритмика Москва
от 120 000 до 200 000 руб.
20 авг. 2019, в 17:35
5000 руб./за проект
20 авг. 2019, в 17:33
2500 руб./за проект
20 авг. 2019, в 17:31
3000 руб./за проект