M
M
Maxim Rysakov2019-07-21 01:08:40
JavaScript
Maxim Rysakov, 2019-07-21 01:08:40

JavaScript (recursion) How to transform one array (catalog) into another (tree)?

How to do it with 1 level is understandable, but how to make recursion so that unlimited nestings are not understandable
f = this nesting level is obtained, from right to left

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

Samsung -> Galaxy -> Tel3
Samsung -> Tel2

At the entrance
[
  {
    "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"
  }
  // ...
]

and at the output I want to get, for the component, building a tree
[
  {
    "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" // Важное
          }
        ]
      }
    ]
  },
  // ...
]

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexey, 2019-07-21
@Azperin

You cycle through the first array and fill in the other according to the conditions you need. Yes, and in the second array, I don’t see an array, there is 1 element in the same place, so it’s easier to omit it

var sourceArr = [...];
var obj = {};
sourceArr.forEach(x => {
  if(x[prop]) // парсиш ипроводиш нужные операции с объектом
  // тотже x.path просто сплитиш по запятой и делаешь внутренний цикл с проверкой obj.hasOwnProperty
  obj[prop] = x[prop] 
})

D
Dmitry Belyaev, 2019-07-21
@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"
  }
  // ...
]));

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question