2017-09-15 5 views
1

j'ai un tableau d'objet avec une structure hiérarchique, quelque chose comme ceci:aplatir javascript tableau d'objets

[ 
    {name: 'ParentOne', children: [ 
     {name: 'ParentOneChildOne'}, 
     {name: 'ParentOneChildTwo', children: [ 
      {name: 'ParentOneChildTwoGrandChildOne'}, 
     ]}, 
    ]}, 
    {name: 'ParentTwo', children: [ 
     {name: 'ParentTwoChildOne', children: [ 
      {name: 'ParentTwoChildOneGrandChildOne'}, 
      {name: 'ParentTwoChildOneGrandChildTwo'} 
     ]}, 
     {name: 'ParentTwoChildTwo'} 
    ]} 
]; 

Je veux aplatir:

[ 
    {name: 'ParentOne'}, 
    {name: 'ParentOneChildOne'}, 
    {name: 'ParentOneChildTwo'}, 
    {name: 'ParentOneChildTwoGrandChildOne'}, 
    {name: 'ParentTwo'}, 
    {name: 'ParentTwoChildOne'}, 
    {name: 'ParentTwoChildOneGrandChildOne'}, 
    {name: 'ParentTwoChildOneGrandChildTwo'}, 
    {name: 'ParentTwoChildTwo'} 
] 

J'ai essayé _.flatten() et _.flatMap(), mais ça ne produit pas ce dont j'ai besoin. Quelle est la meilleure façon d'y parvenir de préférence en utilisant lodash.js ou underscore.js.

Répondre

4

Pas besoin de trait de soulignement/lodash.

const arr = [ 
 
    {name: 'ParentOne', children: [ 
 
     {name: 'ParentOneChildOne'}, 
 
     {name: 'ParentOneChildTwo', children: [ 
 
      {name: 'ParentOneChildTwoGrandChildOne'}, 
 
     ]}, 
 
    ]}, 
 
    {name: 'ParentTwo', children: [ 
 
     {name: 'ParentTwoChildOne', children: [ 
 
      {name: 'ParentTwoChildOneGrandChildOne'}, 
 
      {name: 'ParentTwoChildOneGrandChildTwo'} 
 
     ]}, 
 
     {name: 'ParentTwoChildTwo'} 
 
    ]} 
 
]; 
 

 
function flatten(arr) { 
 
    return arr? arr.reduce((result, item) => [ 
 
     ...result, 
 
     { name: item.name }, 
 
     ...flatten(item.children) 
 
    ], []) : []; 
 
} 
 

 
console.log(flatten(arr));

1

J'utiliser .reduce et récursivité pour le faire. Voici ma mise en œuvre en utilisant Array.reduce, mais vous pourriez faire la même chose avec la fonction de réduction underscore.

const arr = [ 
 
    {name: 'ParentOne', children: [ 
 
     {name: 'ParentOneChildOne'}, 
 
     {name: 'ParentOneChildTwo', children: [ 
 
      {name: 'ParentOneChildTwoGrandChildOne'}, 
 
     ]}, 
 
    ]}, 
 
    {name: 'ParentTwo', children: [ 
 
     {name: 'ParentTwoChildOne', children: [ 
 
      {name: 'ParentTwoChildOneGrandChildOne'}, 
 
      {name: 'ParentTwoChildOneGrandChildTwo'} 
 
     ]}, 
 
     {name: 'ParentTwoChildTwo'} 
 
    ]} 
 
]; 
 

 
function flatten(arr) { 
 
    return arr.reduce((result, current) => { 
 
     if (current.children) { 
 
     const children = flatten(current.children); 
 
     delete current.children; 
 
     result.push(current); 
 
     result.push(...children); 
 
     } else { 
 
     result.push(current); 
 
     } 
 
     return result; 
 
    }, []) 
 
} 
 

 
console.log(flatten(arr));

0

Vous pouvez essayer d'adapter la fonction flatten donnée dans this answer et tourner légèrement la logique à la structure de votre objet.

//Your object 
 
var data = [{ 
 
    name: 'ParentOne', 
 
    children: [{ 
 
     name: 'ParentOneChildOne' 
 
     }, 
 
     { 
 
     name: 'ParentOneChildTwo', 
 
     children: [{ 
 
      name: 'ParentOneChildTwoGrandChildOne' 
 
     }, ] 
 
     }, 
 
    ] 
 
    }, 
 
    { 
 
    name: 'ParentTwo', 
 
    children: [{ 
 
     name: 'ParentTwoChildOne', 
 
     children: [{ 
 
      name: 'ParentTwoChildOneGrandChildOne' 
 
      }, 
 
      { 
 
      name: 'ParentTwoChildOneGrandChildTwo' 
 
      } 
 
     ] 
 
     }, 
 
     { 
 
     name: 'ParentTwoChildTwo' 
 
     } 
 
    ] 
 
    } 
 
]; 
 

 
//georg's flatten function 
 
flatten = function(x, result, prefix) { 
 
    if (_.isObject(x)) { 
 
    _.each(x, function(v, k) { 
 
     flatten(v, result, prefix ? prefix + '_' + k : k) 
 
    }) 
 
    } else { 
 
    result[prefix] = x 
 
    } 
 
    return result 
 
} 
 

 
//using the function on your data 
 
result = flatten(data, {}); 
 
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

cette aide à tous?

2

Les fonctions récursives sont le chemin à parcourir pour toute profondeur d'itération.

Avec un peu ES2015 et LoDash/Souligné

var arr = [{ 
 
    name: 'ParentOne', 
 
    children: [{ 
 
    name: 'ParentOneChildOne' 
 
    }, { 
 
    name: 'ParentOneChildTwo', 
 
    children: [{ 
 
     name: 'ParentOneChildTwoGrandChildOne' 
 
    }, ] 
 
    }, ] 
 
}, { 
 
    name: 'ParentTwo', 
 
    children: [{ 
 
    name: 'ParentTwoChildOne', 
 
    children: [{ 
 
     name: 'ParentTwoChildOneGrandChildOne' 
 
    }, { 
 
     name: 'ParentTwoChildOneGrandChildTwo' 
 
    }] 
 
    }, { 
 
    name: 'ParentTwoChildTwo' 
 
    }] 
 
}]; 
 

 
var res = _.reduce(arr, (a, b) => { 
 
    (rec = item => { 
 
    _.each(item, (v, k) => (_.isObject(v) ? rec(v) : a.push(_.zipObject([k], [v])))) 
 
    })(b); 
 
    return a; 
 
}, []); 
 

 
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

0

Vous pouvez utiliser une destruction et d'utiliser une fonction récursive pour recueillir tous les articles désirés.

var array = [{ name: 'ParentOne', children: [{ name: 'ParentOneChildOne' }, { name: 'ParentOneChildTwo', children: [{ name: 'ParentOneChildTwoGrandChildOne' },] },] }, { name: 'ParentTwo', children: [{ name: 'ParentTwoChildOne', children: [{ name: 'ParentTwoChildOneGrandChildOne' }, { name: 'ParentTwoChildOneGrandChildTwo' }] }, { name: 'ParentTwoChildTwo' }] }], 
 
    flat = (r, { name, children = [] }) => [...r, { name }, ...children.reduce(flat, []) ], 
 
    result = array.reduce(flat, []); 
 
    
 
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

sur le bord, vous avez besoin d'une utilisation différente des valeurs defualt

var array = [{ name: 'ParentOne', children: [{ name: 'ParentOneChildOne' }, { name: 'ParentOneChildTwo', children: [{ name: 'ParentOneChildTwoGrandChildOne' },] },] }, { name: 'ParentTwo', children: [{ name: 'ParentTwoChildOne', children: [{ name: 'ParentTwoChildOneGrandChildOne' }, { name: 'ParentTwoChildOneGrandChildTwo' }] }, { name: 'ParentTwoChildTwo' }] }], 
 
    flat = (r, { name, children }) => [...r, { name }, ...(children || []).reduce(flat, []) ], 
 
    result = array.reduce(flat, []); 
 
    
 
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }