【问题标题】:Merge Unknown number of objects in array into single js object将数组中未知数量的对象合并为单个js对象
【发布时间】:2022-10-06 16:27:22
【问题描述】:

我有一个对象如下

[
    {
        \"config\": {
            \"holes\": 18
        }
    },
    {
        \"config\": {
            \"single_cart\": false
        }
    },
    {
        \"config\": {
            \"shared_cart\": false
        }
    },
    {
        \"config\": {
            \"caddie\": false
        }
    },
    {
        \"config\": {
            \"transfers\": false
        }
    },
    {
        \"config\": {
            \"meals\": false
        }
    },
    {
        \"config\": {
            \"all_inclusive\": false
        }
    }
]

我试图转换成

{
   \"config\":{
      \"holes\":18,
      \"single_cart\":false,
      \"shared_cart\":false,
      \"caddie\":false,
      \"transfers\":false,
      \"meals\":false,
      \"all_inclusive\":false
   }
}

这是一个示例“合并”,因为它们可以是任何名称和值键。我尝试过使用reduce、map、foreach但失败了,并且永远无法将它们连接在一起。

如果有人可以帮助我指出正确的方向,那就太棒了。我看到的所有示例都引用了专门命名的键来使用 object.assign 等进行合并。

  • \"config\" 可以命名为任何名称或只是其中的属性吗?
  • 配置可以命名为任何东西,所以我认为每个人都没有阅读我请求的最后一段
  • 我已经发布了一个可以在不知道任何键(包括“config”)的情况下使用的答案。让我知道它是否有效。

标签: javascript arrays merge


【解决方案1】:

这是一种无需事先知道任何键的方法。

const input = [
  {
    "config": {
      "holes": 18
    }
  },
  {
    "config": {
      "single_cart": false
    }
  },
  {
    "config": {
      "shared_cart": false
    }
  },
  {
    "config": {
      "caddie": false
    }
  },
  {
    "config": {
      "transfers": false
    }
  },
  {
    "config": {
      "meals": false
    }
  },
  {
    "config": {
      "all_inclusive": false
    }
  }
];

const mergeObjects = (a, b) => {
  for (let k in b) {
    if (k in a) {
      if (typeof(a[k]) === 'object' && typeof(b[k]) === 'object') {
        a[k] = mergeObjects(a[k], b[k]);
      } else {
        throw `Unable to merge because key "${k}" is in both objects (and not both values are objects).`;
      }
    } else {
      a[k] = b[k];
    }
  }

  return a;
};

const output = input.reduce(mergeObjects, {});

console.log(output);

【讨论】:

    【解决方案2】:

    您可以使用reduce() 来合并数组中的所有对象。您可以使用... 扩展语法来组合对象。

    const data = [{
        "config": {
          "holes": 18
        }
      },
      {
        "config": {
          "single_cart": false
        }
      },
      {
        "config": {
          "shared_cart": false
        }
      },
      {
        "config": {
          "caddie": false
        }
      },
      {
        "config": {
          "transfers": false
        }
      },
      {
        "config": {
          "meals": false
        }
      },
      {
        "config": {
          "all_inclusive": false
        }
      }
    ];
    
    const result = {
      config: data.reduce((acc, obj) => ({...acc, ...obj.config}), {})
    };
    
    console.log(result);

    【讨论】:

    • 如果我每次都知道对象的尺寸,这将起作用。
    • 我以为您指的是嵌套键,例如 holessingle_cart。我假设config 是已知的,因为它在整个示例中是一致的。
    【解决方案3】:

    我创建了一个codepen here

    它以一种相当简单的方式完成了您正在寻找的事情。

    const data = [
        {
            "config": {
                "holes": 18
            }
        },
        {
            "config": {
                "single_cart": false
            }
        },
        {
            "config": {
                "shared_cart": false
            }
        },
        {
            "config": {
                "caddie": false
            }
        },
        {
            "config": {
                "transfers": false
            }
        },
        {
            "config": {
                "meals": false
            }
        },
        {
            "config": {
                "all_inclusive": false
            }
        }
    ]
    
    const obj = { 
      config: {} 
    }
    
    data.forEach((row) => {
      obj.config[Object.keys(row.config)[0]] = row.config[Object.keys(row.config)[0]];
    })
    
    console.log(obj);
    

    【讨论】:

    • 当您可以在这里使用Stack Snippet 时,为什么还要使用外部代码笔?
    【解决方案4】:

    那应该是一个单行:

    let data = [ 
        {
            "config": {
                "holes": 18
            }
        },
        {
            "config": {
                "single_cart": false
            }
        },
        /* more of your data.... */ 
    ]
    
    const result = data.reduce((prev, {config}) => ({config: {...prev.config, ...config}}), {config: {}})
    

    您可以使用reduce 来展平数组或创建对象。您甚至不需要声明一个单独的变量来分配您的数据。

    如果你有一个默认配置或以前的数据,你想覆盖,你可以改变 reduce 函数的第二个参数:

    
    const defaultConfig = {
        config: {
          "holes": 0,
          "single_cart": true,
        }
    }
    
    const newConfig = data.reduce((prev, {config}) => ({config: {...prev.config, ...config}}), defaultConfig)
    
    

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce 中查看更多信息

    【讨论】:

      【解决方案5】:

      我假设您的列表名为configList。这应该有效:

      const result = { config: {} }
      
      configList.forEach(element => {
         let key = Object.keys(element.config)
         let value = element.config[key]
         
         result.config[key] = value
      })
      
      console.log(result)
         
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-08
        • 2015-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多