【问题标题】:Create new object from array of nested arrays that contains objects从包含对象的嵌套数组数组创建新对象
【发布时间】:2019-04-19 18:16:09
【问题描述】:

我有以下带有嵌套数组的数组:

const options = [
  [
    {
      label: "Blue",
      option_id: "1"
    },
    {

      label: "Small",
      option_id: "2"
    }
  ],
  [
    {
      label: "Red",
      option_id: "1"
    },
    {
      label: "Large",
      option_id: "2"
    }
  ]
];

我想从每一对中创建一个对象数组,例如:

[
 {
   label: ”Blue Small“,
   option_id: [1,2]
 },
...
]

编辑:感谢大家的精彩回答

【问题讨论】:

    标签: javascript arrays


    【解决方案1】:

    options数组上使用.map,并将reduce每个子数组变成一个对象:

    const options = [
      [
        {
          label: "Blue",
          option_id: "1"
        },
        {
    
          label: "Small",
          option_id: "2"
        }
      ],
      [
        {
          label: "Red",
          option_id: "1"
        },
        {
          label: "Large",
          option_id: "2"
        }
      ]
    ];
    const result = options.map(arr =>
      arr.reduce(
        (a, { label, option_id }) => {
          a.label += (a.label ? ' ' : '') + label;
          a.option_id.push(option_id);
          return a;
        },
        { label: '', option_id: [] }
      )
    );
    console.log(result);

    【讨论】:

      【解决方案2】:

      reduce 是这些数组转换的好方法。

      const options = [
        [
          {
            label: "Blue",
            option_id: "1"
          },
          {
      
            label: "Small",
            option_id: "2"
          }
        ],
        [
          {
            label: "Red",
            option_id: "1"
          },
          {
            label: "Large",
            option_id: "2"
          }
        ]
      ];
      
      const newArray = options.reduce((prev,current)=>{
        const label = current.map(o=>o.label).join(' ')
        const optionid = current.map(o=>o.option_id)
        return [...prev,{option_id:optionid,label}]
      },[])
      
      console.log(newArray)
      

      【讨论】:

      • return [...prev, {}] 在这里可能过于花哨。它构建了一个全新的列表,而在这种情况下将累加器 - push 修改为现有列表是完全有效的。
      • 是的,在这里使用push 完全有效,我只是不想修改累加器而是返回一个新值。
      • 我同意@tevemadar。这是一个花哨的return [...prev, {}]。但如果列表很大,则纯粹是性能问题。
      【解决方案3】:

      您可以映射和收集数据。

      const
          options = [[{ label: "Blue", option_id: "1" }, { label: "Small", option_id: "2" }], [{ label: "Red", option_id: "1" }, { label: "Large", option_id: "2" }]],
          result = options.map(a => a.reduce((r, { label, option_id }) => {
              r.label += (r.label && ' ') + label;
              r.option_id.push(option_id);
              return r;
          }, { label: '', option_id: [] }));
      
      console.log(result);
      .as-console-wrapper { max-height: 100% !important; top: 0; }

      【讨论】:

      • 您好,需要一点帮助。 (r.label && ' ') 是什么意思?
      • 它是否切换所需的空间。一开始,r.label 是一个空字符串 ans falsy。这是拍摄并添加了label,没有空格。如果r.label 不是空字符串,它会占用空间并添加label。基本上它是 CertainPerfomance' (a.label ? ' ' : '') 部分的非常短的形式。
      • r.label ? ' ' : ''
      • 谢谢。欣赏它
      【解决方案4】:

      您可以使用map()reduce()

      const options = [
        [
          {
            label: "Blue",
            option_id: "1"
          },
          {
      
            label: "Small",
            option_id: "2"
          }
        ],
        [
          {
            label: "Red",
            option_id: "1"
          },
          {
            label: "Large",
            option_id: "2"
          }
        ]
      ];
      
      const result = options.map((x) => {
        let label = x.reduce((acc, val) => { 
          acc.push(val.label);
          return acc;
        }, []).join(',');
        let optArr = x.reduce((acc, val) => { 
          acc.push(val.option_id);
          return acc;
        }, []);
        return {
          label: label,
          option_id: optArr
        }
      });
      
      console.log(result);

      【讨论】:

        【解决方案5】:

        使用mapreducemap 将返回一个新数组并在 map 的回调函数中,使用 reduce 并默认在累加器中传递一个对象。

        const options = [
          [{
              label: "Blue",
              option_id: "1"
            },
            {
        
              label: "Small",
              option_id: "2"
            }
          ],
          [{
              label: "Red",
              option_id: "1"
            },
            {
              label: "Large",
              option_id: "2"
            }
          ]
        ];
        
        
        
        let k = options.map(function(item) {
          return item.reduce(function(acc, curr) {
            acc.label = `${acc.label} ${curr.label}`.trim();
            acc.option_id.push(curr.option_id)
        
            return acc;
          }, {
            label: '',
            option_id: []
          })
        });
        
        console.log(k)

        【讨论】:

          【解决方案6】:

          你总是可以迭代地接近,首先用编号的for循环写东西:

          const options = [[{label: "Blue",option_id: "1"},{label: "Small",option_id: "2"}],
                           [{label: "Red",option_id: "1"},{label: "Large",option_id: "2"}]];
            
          const result = [];
          for(var i=0; i<options.length; i++){
            var arr = options[i];
            var labels = [];
            var ids = [];
            for(var j=0; j<arr.length; j++){
              var opt = arr[j];
              labels.push(opt.label);
              ids.push(opt.option_id);
            }
            result.push({label:labels.join(" "),option_id:ids});
          }
          console.log(result);

          然后用forEach扔掉索引

          const options = [[{label: "Blue",option_id: "1"},{label: "Small",option_id: "2"}],
                           [{label: "Red",option_id: "1"},{label: "Large",option_id: "2"}]];
            
          const result = [];
          options.forEach(arr => {
            var labels = [];
            var ids = [];
            arr.forEach(opt => {
              labels.push(opt.label);
              ids.push(opt.option_id);
            });
            result.push({label:labels.join(" "),option_id:ids});
          });
          console.log(result);

          那么外循环可以很简单map-ed:

          const options = [[{label: "Blue",option_id: "1"},{label: "Small",option_id: "2"}],
                           [{label: "Red",option_id: "1"},{label: "Large",option_id: "2"}]];
            
          const result = options.map(arr => {
            var labels = [];
            var ids = [];
            arr.forEach(opt => {
              labels.push(opt.label);
              ids.push(opt.option_id);
            });
            return {label:labels.join(" "),option_id:ids};
          });
          console.log(result);

          并尝试reduce内循环:

          const options = [[{label: "Blue",option_id: "1"},{label: "Small",option_id: "2"}],
                           [{label: "Red",option_id: "1"},{label: "Large",option_id: "2"}]];
            
          const result = options.map(arr => 
            (lists => ({label:lists.labels.join(" "),option_id:lists.ids}))
            (arr.reduce((lists,opt) => {
              lists.labels.push(opt.label);
              lists.ids.push(opt.option_id);
              return lists;
            },{labels:[],ids:[]}))
          );
          console.log(result);

          arr.reduce 是这里lists =&gt; 函数的参数(它替换了前面sn-ps 中的简单return 行)。我只是想保留join,但这种方式可能有点过头了。因此,改为保留显式变量不会有任何问题。

          【讨论】:

            猜你喜欢
            • 2022-01-18
            • 1970-01-01
            • 2019-10-06
            • 2021-11-28
            • 2021-08-02
            • 1970-01-01
            • 2022-01-08
            • 2020-12-21
            • 2019-04-23
            相关资源
            最近更新 更多