Задать вопрос

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" // Важное
          }
        ]
      }
    ]
  },
  // ...
]
  • Вопрос задан
  • 500 просмотров
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 2
@Azperin
Дилетант
Прогоняешь циклом первый массив и заполняешь другой по условиям которые тебе нужны. Да и во втором массиве я массива то не вижу, там же 1 элемент, поэтому проще его опустить
var sourceArr = [...];
var obj = {};
sourceArr.forEach(x => {
  if(x[prop]) // парсиш ипроводиш нужные операции с объектом
  // тотже x.path просто сплитиш по запятой и делаешь внутренний цикл с проверкой obj.hasOwnProperty
  obj[prop] = x[prop] 
})
Ответ написан
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
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"
  }
  // ...
]));
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы