我如何重组这些数据以匹配其原始 un-flattened 形状?

How can I restructure this data to match it's original un-flattened shape?

我有以下数据模型:

新模式

[
        {
            name : 'Tony',
            id : 'Tony_id'
        },{
            name: 'Barry',
            id: 'Barry_id',
            parentId: 'Tony_id'
        },{
            name: 'George',
            id: 'George_id',
            parentId: 'Barry_id'
        },{
            name : 'Laura',
            id : 'Laura_id',
            parentId: 'Barry_id'
        },{
            name: 'Edward',
            id: 'Edward_id'
        },{
            name: 'Patrick',
            id: 'Patrick_id',
            parentId: 'Edward_id'
        }
   ]

所以结构是parents、children和grandchildren。最初模型如下所示,但我不得不将其展平:

旧型号

   [

        {
            name : 'Tony',
            id : 'Tony_id',
            children: [
                {
                    name: 'Barry',
                    id: 'Barry_id',
                    parentId: 'Tony_id',
                    children: [
                        {
                            name: 'George',
                            id: 'George_id',
                            parentId: 'Barry_id'
                        },{
                            name : 'Laura',
                            id : 'Laura_id',
                            parentId: 'Barry_id'
                        }
                    ]
                }
            ]
        },{
            name: 'Edward',
            id: 'Edward_id',
            children: [
                {
                    name: 'Patrick',
                    id: 'Patrick_id',
                    parentId: 'Edward_id'
                 }
            ]
        }
   ]

我丢失了对旧模型的任何引用。

只使用新模型,如何重组它以匹配我的旧模型,到un-flatten呢?

你可以递归地做:

var newData = [

        {
            name : 'Tony',
            id : 'Tony_id',
            children: [
                {
                    name: 'Barry',
                    id: 'Barry_id',
                    parentId: 'Tony_id',
                    children: [
                        {
                            name: 'George',
                            id: 'George_id',
                            parentId: 'Barry_id'
                        },{
                            name : 'Laura',
                            id : 'Laura_id',
                            parentId: 'Barry_id'
                        }
                    ]
                }
            ]
        },{
            name: 'Edward',
            id: 'Edward_id',
            children: [
                {
                    name: 'Patrick',
                    id: 'Patrick_id',
                    parentId: 'Edward_id'
                 }
            ]
        }
   ];

function flat(datas, flatten) {
    datas.forEach(el => {
        flatten.push(el);
        if (el.children) {
            flat(el.children, flatten);
            delete el.children;
        }
    });
}

var flatten = [];
flat(newData, flatten);
console.log(flatten);

编辑:反向操作:

var data = [{ name: 'Tony', id: 'Tony_id' }, { name: 'Barry', id: 'Barry_id', parentId: 'Tony_id' }, { name: 'George', id: 'George_id', parentId: 'Barry_id' }, { name: 'Laura', id: 'Laura_id', parentId: 'Barry_id' }, { name: 'Edward', id: 'Edward_id' }, { name: 'Patrick', id: 'Patrick_id', parentId: 'Edward_id' }];

function ToTree(arrayItems) {
    var map = {}, roots = [];
    arrayItems.forEach((item, i) => {
        map[item.id] = i;
        item.children = [];
    });
    arrayItems.forEach(node => {
        if (node.parentId && arrayItems[map[node.parentId]]) {
            arrayItems[map[node.parentId]].children.push(node);
        } else {
            roots.push(node);
        }
    });
    return roots;    
}

var myTree = ToTree(data);
console.log(myTree);

您可以构建一个带有 object 的树来保持 parents 和 children 关系。

此提议也适用于未排序的数据。

var data = [{ name: 'Tony', id: 'Tony_id' }, { name: 'Barry', id: 'Barry_id', parentId: 'Tony_id' }, { name: 'George', id: 'George_id', parentId: 'Barry_id' }, { name: 'Laura', id: 'Laura_id', parentId: 'Barry_id' }, { name: 'Edward', id: 'Edward_id' }, { name: 'Patrick', id: 'Patrick_id', parentId: 'Edward_id' }],
    tree = function (data, root) {
        var r = [], o = {};
        data.forEach(function (a) {
            if (o[a.id] && o[a.id].children) {
                a.children = o[a.id] && o[a.id].children;
            }
            o[a.id] = a;
            if (a.parentId === root) {
                r.push(a);
            } else {
                o[a.parentId] = o[a.parentId] || {};
                o[a.parentId].children = o[a.parentId].children || [];
                o[a.parentId].children.push(a);
            }
        });
        return r;
    }(data, undefined);

console.log(tree);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

和(为了好玩)相反:

let oldData = [
  {name : 'Tony', id : 'Tony_id'},
  {name: 'Barry', id: 'Barry_id', parentId: 'Tony_id'},
  {name: 'George', id: 'George_id', parentId: 'Barry_id'},
  {name : 'Laura', id : 'Laura_id', parentId: 'Barry_id'},
  {name: 'Edward', id: 'Edward_id'},
  {name: 'Patrick', id: 'Patrick_id', parentId: 'Edward_id'}
]

// First we need a Key-Data object with :
// Key   : person's id
// Value : person's data
let dwKeys = {}
oldData.forEach( d => dwKeys[d.id] = d) ;


// The same objects with children

let dwChildren = {} ;

// Then we can know who's who

for(let uid in dwKeys)
{
    
  // We take the person's data
  let udata = dwKeys[uid] ;
  
  // we take the parent (if any)
  
  let parentId = udata.parentId ;
  
  // No parent ? OK => root person
  
  if ( ! parentId ) {
    dwChildren[uid] = udata ;
    continue ; 
  } 
    
  // Now, we add the child to their parent
  
  // Do the record if needed
  
  if ( undefined === dwChildren[parentId] ){ 
    dwChildren[parentId] = dwKeys[parentId] ;
  }
  
  // Do the children field if needed
  
  if (undefined === dwChildren[parentId]['children'] ){
    dwChildren[parentId]['children'] = [];
  }
  
  // Add this child
  
  delete udata.parentId ;
  dwChildren[parentId]['children'].push(udata);
  
}

// Hey no, it doesn't work:
// dwChildren = dwChildren.values() ;
// So:

let awChildren = [] ; // for "Array With Children"

for (let uid in dwChildren ) { awChildren.push(dwChildren[uid]) }


console.log(awChildren);
.as-console-wrapper { max-height: 100% !important; top: 0; }