【问题标题】:Merge keys array and values array into an object in JavaScript将键数组和值数组合并到 JavaScript 中的对象中
【发布时间】:2010-11-10 05:09:39
【问题描述】:

我有:

var keys = [ "height", "width" ];
var values = [ "12px", "24px" ];

我想把它转换成这个对象:

{ height: "12px", width: "24px" }

在 Python 中,有一个简单的习语 dict(zip(keys,values))。 jQuery 或纯 JavaScript 中是否有类似的东西,还是我必须长期这样做?

【问题讨论】:

标签: javascript json object


【解决方案1】:
function combineObject( keys, values)
{
    var obj = {};
    if ( keys.length != values.length)
       return null;
    for (var index in keys)
        obj[keys[index]] = values[index];
     return obj;
};


var your_obj = combine( your_keys, your_values);

【讨论】:

  • 嘿,我看到你修复了它,所以删除了评论,然后你回复了 - 为异步对话欢呼:D你还应该避免使用新对象,因为对象可能会更改,但 {} 是规范'd 就像使用原始的 Object 构造函数一样。
  • 函数还是不正确。 combineObject(["height", "width"], ["12px", "24px"]).height 错误地返回 "24px"。
  • 谢谢我已经根据您的评论修复了它,但我不确定这可能是一个问题,因为一旦有人更改了对象,它就是故意的,所以最好隐含在所有对象上你会有的。
【解决方案2】:

简单的 JS 函数是:

function toObject(names, values) {
    var result = {};
    for (var i = 0; i < names.length; i++)
         result[names[i]] = values[i];
    return result;
}

当然,您也可以实际实现诸如 zip 之类的功能,因为 JS 支持高阶类型,这使得这些功能语言主义变得容易:D

【讨论】:

  • 如果名字有相同的key,这个函数会失败。
  • @user1927627 不,不会。它将只使用最后一次出现,正如人们所期望的那样。
  • 帮助设置多个数组值的标题。然后作为对象问。值[0].宽度; var header = [“高度”,“宽度”]; var values[0] = [ "12px", "24px" ];变量值[1] = [ "14px", "33px" ]; /*或*/ var header= [ "height", "width" ]; var values = [[ "12px", "24px" ], [ "14px", "33px" ]];有什么想法吗?
【解决方案3】:

jQuery-Utils project中,ArrayUtils模块实现了zip功能。

//...
zip: function(object, object2, iterator) {
    var output = [];
    var iterator = iterator || dummy;
        $.each(object, function(idx, i){
        if (object2[idx]) { output.push([i, object2[idx]]); }
    });
    return output;
}
//...

【讨论】:

  • 嗯,但是你如何处理元组数组呢?
【解决方案4】:

您可以使用reduce() 函数将键值对映射到对象。

/**
 *  Apply to an existing or new object, parallel arrays of key-value pairs.
 *
 *  @param   {string[]} keys      - List of keys corresponding to their accociated values.
 *  @param   {object[]} vals      - List of values corresponding to their accociated keys.
 *  @param   {object}   [ref={}]  - Optional reference to an existing object to apply to.
 *
 *  @returns {object} - The modified or new object with the new key-value pairs applied.
 */
function toObject(keys, vals, ref) {
  return keys.length === vals.length ? keys.reduce(function(obj, key, index) {
    obj[key] = vals[index];
    return obj;
  }, ref || {}) : null;
}

var keys   = [ "height" , "width" ];
var values = [ "12px"   , "24px"  ];

document.body.innerHTML = '<pre>' + JSON.stringify(toObject(keys, values), null, 2) + '</pre>';

【讨论】:

    【解决方案5】:

    使用 lodash。

    _.zipObject

    例子

    _.zipObject(['a', 'b'], [1, 2]);
    // ➜ { 'a': 1, 'b': 2 }
    

    【讨论】:

    • 这应该是公认的答案。自己滚动(就像所有其他答案一样)是浪费时间。 Underscore 中这个函数的原始名称(您也可以在旧版本的 Lodash 中找到)是 _.object
    【解决方案6】:

    作为替代解决方案,我认为尚未提及:

      var result = {};
      keys.forEach((key, idx) => result[key] = values[idx]);
    

    【讨论】:

      【解决方案7】:

      使用数组reduce的最简单的ES6单行解决方案:

      const keys = ['height', 'width'];
      const values = ['12px', '24px'];
      const merged = keys.reduce((obj, key, index) => ({ ...obj, [key]: values[index] }), {});
      

      【讨论】:

      • 正确的现代版
      【解决方案8】:

      考虑到不变性的函数式方法:

      const zipObj = xs => ys => xs.reduce( (obj, x, i) => ({ ...obj, [x]: ys[i] }), {})
      
      const arr1 = ['a', 'b', 'c', 'd']
      const arr2 = ['e', 'f', 'g', 'h']
      
      const obj = zipObj (arr1) (arr2) 
      
      console.log (obj)

      【讨论】:

      • 你能指出一些关于 zipObj(arr1, arr2) 和 zipObj(arr1)(arr2) 的详细区别的文档吗?
      • @JefersonEuclides 嘿嘿,第二种叫做柯里化和偏应用。
      【解决方案9】:

      你可以用map方法合并两个数组,然后用Object.fromEntries进行转换。

      var keys = ["height", "width"];
      var values = ["12px", "24px"];
      
      var array = keys.map((el, i) => {
        return [keys[i], values[i]];
      });
      // → [["height", "12px"], ["width", "24px"]]
      
      var output = Object.fromEntries(array);
      // → {height: "12px", width: "24px"}
      console.log(output);

      【讨论】:

        【解决方案10】:

        您可以转置数组并获取带有条目的对象。

        const
            transpose = (r, a) => a.map((v, i) => [...(r[i] || []), v]),
            keys = [ "height", "width" ],
            values = [ "12px", "24px" ],
            result = Object.fromEntries([keys, values].reduce(transpose, []));
        
        console.log(result);

        【讨论】:

          【解决方案11】:

          这是一个包含所有 const(非修改)且没有库的示例。

          const keys = ["Adam", "Betty", "Charles"];
          const values = [50, 1, 90];
          const obj = keys.reduce((acc, key, i) => {
            acc[key] = values[i];
            return acc;
          }, {});
          console.log(obj);

          或者,如果您考虑使用库,您可以使用 lodash zipobject,它可以满足您的要求。

          【讨论】:

            【解决方案12】:

            这是一个将嵌套数组转换为多个键值对象数组的方法。

            var keys = [
              ['#000000', '#FFFFFF'],
              ['#FFFF00', '#00FF00', '#00FFFF', '#0000FF'],
            ];
            var values = [
              ['Black', 'White'],
              ['Yellow', 'Green', 'Cyan', 'Blue'],
            ];
            const zipObj = xs => ys => xs.reduce( (obj, x, i) => ({ ...obj, [x]: ys[i] }), {})
            var array = keys.map((el, i) => zipObj (keys[i]) (values[i]));
            
            console.log(array);

            输出是

            [
              {
                "#000000": "Black",
                "#FFFFFF": "White"
              },
              {
                "#FFFF00": "Yellow",
                "#00FF00": "Green",
                "#00FFFF": "Cyan",
                "#0000FF": "Blue"
              }
            ]
            

            【讨论】:

              【解决方案13】:

              现在我们有了Object.fromEntries,我们可以这样做:

              const keys = [ "height", "width" ];
              const values = [ "12px", "24px" ];
              const myObject = Object.fromEntries(
                  values.map((value, index) => [keys[index], value])
              );
              
              console.log(myObject);

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2019-06-28
                • 2018-10-14
                • 1970-01-01
                • 2020-07-04
                • 2016-10-02
                • 2011-04-04
                • 1970-01-01
                相关资源
                最近更新 更多