Массив карты внутри массива с использованием lodash - PullRequest
0 голосов
/ 10 мая 2019

Я пытаюсь манипулировать этим образцом массива объектов.

var data = [
  { id: 'A', name: 'Test1', parentId: null },
  { id: 'B', name: 'Test2', parentId: 'A'},
  { id: 'C', name: 'Test3', parentId: 'A'},
  { id: 'D', name: 'Test4', parentId: null },
  { id: 'E', name: 'Test5', parentId: 'D'},
  { id: 'F', name: 'Test6', parentId: 'D'},
];

Что мне нужно сделать, это сопоставить массив с таким массивом

var data = [
  {
    id: 'A', 
    name: 'Test1', 
    parentId: null, 
    children:[
      { id: 'B', name: 'Test2', parentId: 'A'},
      { id: 'C', name: 'Test3', parentId: 'A'}
    ],
  },
  {
    id: 'D', 
    name: 'Test4', 
    parentId: null, 
    children:[
      { id: 'E', name: 'Test5', parentId: 'D'},
      { id: 'F', name: 'Test6', parentId: 'D'}
    ],
  },
];

Что является самым простымспособ сделать это, используя lodash?Пожалуйста, помогите мне.

Ответы [ 4 ]

0 голосов
/ 10 мая 2019

Вы можете использовать однопетлевой подход, который переносит отношения между детьми и родителями, родителями и детьми в хеш-таблицу и перезапускает только потомков указанных корневых узлов.

var data = [{ id: 'A', name: 'Test1', parentId: null }, { id: 'B', name: 'Test2', parentId: 'A'}, { id: 'C', name: 'Test3', parentId: 'A'}, { id: 'D', name: 'Test4', parentId: null }, { id: 'E', name: 'Test5', parentId: 'D'}, { id: 'F', name: 'Test6', parentId: 'D'}],
    tree = function(data, root) {
        var t = {};
        data.forEach(o => {
            Object.assign(t[o.id] = t[o.id] || {}, o);
            t[o.parentId] = t[o.parentId] || { id: o.parentId };
            t[o.parentId].children = t[o.parentId].children || [];
            t[o.parentId].children.push(t[o.id]);
        });
        return t[null].children;
    }(data, null);

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 10 мая 2019

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

var data = [{ id: 'A', name: 'Test1', parentId: null },{ id: 'B', name: 'Test2', parentId: 'A'},{ id: 'C', name: 'Test3', parentId: 'A'},{ id: 'D', name: 'Test4', parentId: null },{ id: 'E', name: 'Test5', parentId: 'D'},{ id: 'F', name: 'Test6', parentId: 'D'}];

function tree(data, parentId = null) {
  return _.reduce(data, (r, e) => {
    if (parentId == e.parentId) {
      const o = _.clone(e);
      const children = tree(data, e.id);
      if (children.length) o.children = children;
      r.push(o)
    }
    return r;
  }, [])
}

const result = tree(data);
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
0 голосов
/ 10 мая 2019

Использование _.groupBy наиболее близко к вашим потребностям, просто выберите parentId, как было сказано ранее. Если вам нужно, чтобы он был рекурсивным, вы можете попробовать что-то вроде этого:

var data = [
  { id: 'A', name: 'Test1', parentId: null },
  { id: 'B', name: 'Test2', parentId: 'A'},
  { id: 'C', name: 'Test3', parentId: 'A'},
  { id: 'D', name: 'Test4', parentId: null },
  { id: 'E', name: 'Test5', parentId: 'B'},
  { id: 'F', name: 'Test6', parentId: 'D'},
];

function assignChildrens(grouped, parentId) {
    if (!grouped[parentId]) return [];
    return _.map(grouped[parentId], v => {
        v.childrens = assignChildrens(grouped, v.id);
        return v;
    });
}

var finalData = assignChildrens(_.groupBy(data, 'parentId'), null);

Таким образом, вы могли бы иметь вложенные элементы и все еще работать.

0 голосов
/ 10 мая 2019

_.groupBy более эффективен в таких сценариях. Вам нужно сгруппировать элементы по parentId, чтобы потом можно было легко назначить их потомков.

var data = [
  { id: 'A', name: 'Test1', parentId: null },
  { id: 'B', name: 'Test2', parentId: 'A'},
  { id: 'C', name: 'Test3', parentId: 'A'},
  { id: 'D', name: 'Test4', parentId: null },
  { id: 'E', name: 'Test5', parentId: 'D'},
  { id: 'F', name: 'Test6', parentId: 'D'},
];

var map = _.groupBy(data, 'parentId');
map[null].forEach(item => item.children = map[item.id]);
console.log(map[null]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
...