递归映射功能

时间:2019-01-17 22:37:33

标签: javascript recursion

我很难弄清楚如何执行此递归映射功能。 我有一个看起来像这样的数组。

var array = [
      {
        id: 1,
        label: 'Satisfied customers',
        children: [
          {
            id: 2,
            label: 'Good food',
            icon: 'restaurant_menu',
            children: [

              { id: 3, label: 'Quality ingredients'},
              { id: 4, label: 'Good recipe' }
            ]
          },
          {
            id: 5,
            label: 'Good service',
            icon: 'room_service',
            children: [
              { id: 6, label: 'Prompt attention' },
              { id: 7, label: 'Professional waiter' }
            ]
          },
          {
            id: 8,
            label: 'Pleasant surroundings',
            icon: 'photo',
            children: [
              {
                id: 9,
                label: 'Happy atmosphere (not tickable)',
                tickable: false,
              },
              {
                id: 10,
                label: 'Good table presentation (disabled node)',
                disabled: true,
              },
              {
                id: 11,
                label: 'Pleasing decor',
              }
            ]
          },
          {
            id: 12,
            label: 'Extra information (has no tick)',
            noTick: true,
            icon: 'photo'
          },
          {
            id: 13,
            label: 'Forced tick strategy (to "strict" in this case)',
            tickStrategy: 'strict',
            icon: 'school',
            children: [
              {
                id: 14,
                label: 'Happy atmosphere',
              },
              {
                id: 15,
                label: 'Good table presentation',
              },
              {
                id: 16,
                label: 'Very pleasing decor',
              }
            ]
          }
        ]
      }
    ];

这是数组看起来像... enter image description here

您可以看到孩子是recursive

我需要将它们放入一个数组中。 我的代码不起作用,并且有错误。

const result = [];   
const map = (e) => {

    result.push({
        id: e.id,
        label: e.label,
    })

    e.children.map(map)


};

array.map(map);

错误出现在e.children.map(map)上。 enter image description here

我需要将它们全部推送到数组变量中,但是我不知道该怎么做。 TY

2 个答案:

答案 0 :(得分:2)

使用香草JavaScript学习mutual recursion的好方法-

const transform1 = ({ id = 0, label = "", children = [] }) =>
  [ { id, label }, ...transformAll (children) ] // calls transformAll

const transformAll = (children = []) =>
  children .flatMap (c => transform1 (c)) // calls transform1

console.log(transformAll(array))

输出-

[
  {
    "id": 1,
    "label": "Satisfied customers"
  },
  {
    "id": 2,
    "label": "Good food"
  },
  {
    "id": 3,
    "label": "Quality ingredients"
  },
  {
    "id": 4,
    "label": "Good recipe"
  },
  {
    "id": 5,
    "label": "Good service"
  },
  {
    "id": 6,
    "label": "Prompt attention"
  },
  {
    "id": 7,
    "label": "Professional waiter"
  },
  {
    "id": 8,
    "label": "Pleasant surroundings"
  },
  {
    "id": 9,
    "label": "Happy atmosphere (not tickable)"
  },
  {
    "id": 10,
    "label": "Good table presentation (disabled node)"
  },
  {
    "id": 11,
    "label": "Pleasing decor"
  },
  {
    "id": 12,
    "label": "Extra information (has no tick)"
  },
  {
    "id": 13,
    "label": "Forced tick strategy (to \"strict\" in this case)"
  },
  {
    "id": 14,
    "label": "Happy atmosphere"
  },
  {
    "id": 15,
    "label": "Good table presentation"
  },
  {
    "id": 16,
    "label": "Very pleasing decor"
  }
]

展开下面的代码段,以在您自己的浏览器中验证结果-

var array = [
      {
        id: 1,
        label: 'Satisfied customers',
        children: [
          {
            id: 2,
            label: 'Good food',
            icon: 'restaurant_menu',
            children: [

              { id: 3, label: 'Quality ingredients'},
              { id: 4, label: 'Good recipe' }
            ]
          },
          {
            id: 5,
            label: 'Good service',
            icon: 'room_service',
            children: [
              { id: 6, label: 'Prompt attention' },
              { id: 7, label: 'Professional waiter' }
            ]
          },
          {
            id: 8,
            label: 'Pleasant surroundings',
            icon: 'photo',
            children: [
              {
                id: 9,
                label: 'Happy atmosphere (not tickable)',
                tickable: false,
              },
              {
                id: 10,
                label: 'Good table presentation (disabled node)',
                disabled: true,
              },
              {
                id: 11,
                label: 'Pleasing decor',
              }
            ]
          },
          {
            id: 12,
            label: 'Extra information (has no tick)',
            noTick: true,
            icon: 'photo'
          },
          {
            id: 13,
            label: 'Forced tick strategy (to "strict" in this case)',
            tickStrategy: 'strict',
            icon: 'school',
            children: [
              {
                id: 14,
                label: 'Happy atmosphere',
              },
              {
                id: 15,
                label: 'Good table presentation',
              },
              {
                id: 16,
                label: 'Very pleasing decor',
              }
            ]
          }
        ]
      }
    ];
    
const transform1 = ({ id = 0, label = "", children = [] }) =>
  [ { id, label }, ... transformAll (children) ]
  
const transformAll = (children = []) =>
  children .flatMap (c => transform1 (c))
  
console.log(transformAll(array))


平地之旅

如果您以前从未见过.flatMap-

xs.flatMap(f) == xs.map(f).reduce((a,b) => a.concat(b), [])
xs.flatMap(f) == xs.reduce((a,b) => a.concat(f(b)), [])

最好通过一个简单的演示来查看-

const twice = x =>
  [ x, x ]
  
console .log
  ( [ 'a', 'b', 'c' ] .flatMap (twice) // [ 'a', 'a', 'b', 'b', 'c', 'c' ]
  , [ 1, 2, 3, 4, 5 ] .flatMap (twice) // [ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 ]
  )

flatMap对所有事物都有用-

const tree =
  [ 0, [ 1 ], [ 2, [ 3 ], [ 4, [ 5 ] ] ] ]
  
const all = ([ value, ...children ]) =>
  [ value, ...children .flatMap (all) ]
  
console .log (all (tree))
// [ 0, 1, 2, 3, 4, 5 ]

真的很酷-

const ranks =
  [ 'J', 'Q', 'K', 'A' ]
  
const suits =
  [ '♡', '♢', '♤', '♧' ]

const cards =
  ranks .flatMap (r =>
  suits .flatMap (s =>
  [ [ r, s ] ]
  ))

console .log (cards)
// [ ['J','♡'], ['J','♢'], ['J','♤'], ['J','♧']
// , ['Q','♡'], ['Q','♢'], ['Q','♤'], ['Q','♧']
// , ['K','♡'], ['K','♢'], ['K','♤'], ['K','♧']
// , ['A','♡'], ['A','♢'], ['A','♤'], ['A','♧']
// ]

答案 1 :(得分:1)

您需要检查当前项是否具有children元素,而可以使用forEach来代替,因为map返回新数组,而forEach仅抛出每个元素。

const cb = (e) => {
    res.push({
        id: e.id,
        label: e.label,
    });
    e.children && e.children.forEach(cb);
}
array.forEach(cb);