【问题标题】:Reduce function push into array value减少函数推入数组值
【发布时间】:2020-03-29 20:44:25
【问题描述】:

我有一组对象:

const items = [{ search_type: 'environment',
    search_code: 'TBA_ENVIRONMENT00002',
    asset_code: 'ASSET00002' },
  { search_type: 'job',
    search_code: 'TBA_JOB00002',
    asset_code: 'ASSET00002' },
  { search_type: 'environment',
    search_code: 'TBA_ENVIRONMENT00002',
    asset_code: 'ASSET00004' },
  { search_type: 'job',
    search_code: 'TBA_JOB00002',
    asset_code: 'ASSET00004' },
  { search_type: 'job',
    search_code: 'TBA_JOB00003',
    asset_code: 'ASSET00004' },
  { search_type: 'scene',
    search_code: 'TBA_SCENE00006',
    asset_code: 'ASSET00002' },
 ];

并希望返回类似于以下内容的内容:

{
ASSET00002: {
   environment:["TBA_ENVIRONMENT00002"],
   job:["TBA_JOB00002"],
   scene:["TBA_SCENE00006"]
},
ASSET00004: {
   environment:["TBA_ENVIRONMENT00002"],
   job:["TBA_JOB00002","TBA_JOB00003"]
},
}

这里我使用 Reduce 函数使用了这个逻辑:

const result = items.reduce((acc, item) => {
  const { search_type, search_code, asset_code } = item;
  return {
    ...acc,
    [asset_code]: {
      ...acc[asset_code], [search_type]: [search_code]
    },
  };
}, {});

我得到以下结果:

{
ASSET00002: {
   environment:["TBA_ENVIRONMENT00002"],
   job:["TBA_JOB00002"],
   scene:["TBA_SCENE00006"]
},
ASSET00004: {
   environment:["TBA_ENVIRONMENT00002"],
   job:["TBA_JOB00003"]
},
}

在返回 "ASSET00004"-> "job" 时,我应该得到具有两个值的数组,但只有一个。 我知道我的代码中缺少一些内容,但找不到将值正确推送到数组中的方法。 任何帮助将不胜感激。

【问题讨论】:

    标签: javascript reduce


    【解决方案1】:

    您可以通过单个 reduce 方法完成此操作,确保在迭代对象时添加到任何现有数组:

    const items = [{ search_type: 'environment',
        search_code: 'TBA_ENVIRONMENT00002',
        asset_code: 'ASSET00002' },
      { search_type: 'job',
        search_code: 'TBA_JOB00002',
        asset_code: 'ASSET00002' },
      { search_type: 'environment',
        search_code: 'TBA_ENVIRONMENT00002',
        asset_code: 'ASSET00004' },
      { search_type: 'job',
        search_code: 'TBA_JOB00002',
        asset_code: 'ASSET00004' },
      { search_type: 'job',
        search_code: 'TBA_JOB00003',
        asset_code: 'ASSET00004' },
      { search_type: 'scene',
        search_code: 'TBA_SCENE00006',
        asset_code: 'ASSET00002' },
     ];
    
    const assets = items.reduce((acc, el) => {
      if (!acc[el.asset_code]) {
        acc[el.asset_code] = {};
      }
      acc[el.asset_code][el.search_type] = 
        [...acc[el.asset_code][el.search_type] || [], el.search_code];
      return acc;
    }, {});
    
    console.log(assets);

    【讨论】:

      【解决方案2】:

      问题在于,因为这条线

      [asset_code]: {
       ...acc[asset_code], [search_type]: [search_code]
      },
      

      您正在丢失存储在 search_type 数组中的先前值的上下文,它只获取您推送给它的最新值。

      我们需要检查对象中是否已经存在数组键,如果不存在,则创建一个新数组,如果存在,则将其推送到同一个数组中。

      代码可以修改如下。

      const result = items.reduce((acc, item, i) => {
        const { search_type, search_code, asset_code } = item;
        return {
          ...acc,
          [asset_code]: {
            ...acc[asset_code],
            [search_type]: acc[asset_code] && acc[asset_code][search_type] ?
             acc[asset_code][search_type].concat([search_code]) : [search_code]
          }
        };
      }, {});
      

      在上面的代码中,我们正在检查数组中是否已经存在值,如果存在则将其连接起来。

      【讨论】:

        【解决方案3】:

        因此,您不会向 search_type 键添加任何内容。

        下面的代码使用扩展运算符添加到数组中。

        const items = [{ search_type: 'environment',
            search_code: 'TBA_ENVIRONMENT00002',
            asset_code: 'ASSET00002' },
          { search_type: 'job',
            search_code: 'TBA_JOB00002',
            asset_code: 'ASSET00002' },
          { search_type: 'environment',
            search_code: 'TBA_ENVIRONMENT00002',
            asset_code: 'ASSET00004' },
          { search_type: 'job',
            search_code: 'TBA_JOB00002',
            asset_code: 'ASSET00004' },
          { search_type: 'job',
            search_code: 'TBA_JOB00003',
            asset_code: 'ASSET00004' },
          { search_type: 'scene',
            search_code: 'TBA_SCENE00006',
            asset_code: 'ASSET00002' },
         ];
        /*
        
        {
        ASSET00002: {
           environment:["TBA_ENVIRONMENT00002"],
           job:["TBA_JOB00002"],
           scene:["TBA_SCENE00006"]
        },
        ASSET00004: {
           environment:["TBA_ENVIRONMENT00002"],
           job:["TBA_JOB00002","TBA_JOB00003"]
        },
        }*/
        
        const res = items.reduce((acc, {asset_code, search_type, search_code}) => ({
          ...acc,
          [asset_code]: {
            ...acc[asset_code],
            [search_type]: [
              // this is where you add to your array, this doesn't guarentee uniqueness however
              ...(acc[asset_code] && acc[asset_code][search_type] || []),
              search_code
            ] 
          }
        }), {})
        
        console.log(res)

        【讨论】:

          【解决方案4】:

          非 ES6 解决方案。

          const items = [{ search_type: 'environment',
              search_code: 'TBA_ENVIRONMENT00002',
              asset_code: 'ASSET00002' },
            { search_type: 'job',
              search_code: 'TBA_JOB00002',
              asset_code: 'ASSET00002' },
            { search_type: 'environment',
              search_code: 'TBA_ENVIRONMENT00002',
              asset_code: 'ASSET00004' },
            { search_type: 'job',
              search_code: 'TBA_JOB00002',
              asset_code: 'ASSET00004' },
            { search_type: 'job',
              search_code: 'TBA_JOB00003',
              asset_code: 'ASSET00004' },
            { search_type: 'scene',
              search_code: 'TBA_SCENE00006',
              asset_code: 'ASSET00002' },
           ];
          
          
            var result = {};
             items.forEach( function (item) {            
                result[item.asset_code]  = result[item.asset_code] || {};
                if(result[item.asset_code][item.search_type]){
                  result[item.asset_code][item.search_type].push(item.search_code);
                }else{
                  result[item.asset_code][item.search_type] = new Array(item.search_code)
                }
             });
          
             console.log(result);

          【讨论】:

            猜你喜欢
            • 2018-10-09
            • 1970-01-01
            • 2010-12-13
            • 2019-03-15
            • 2023-03-06
            • 2018-02-16
            • 1970-01-01
            • 1970-01-01
            • 2018-12-01
            相关资源
            最近更新 更多