首页 文章

将数组转换为对象

提问于
浏览
361

转换的最佳方式是什么:

['a','b','c']

至:

{
  0: 'a',
  1: 'b',
  2: 'c'
}

30 回答

  • 8

    使用这样的函数:

    function toObject(arr) {
      var rv = {};
      for (var i = 0; i < arr.length; ++i)
        rv[i] = arr[i];
      return rv;
    }
    

    你的数组已经或多或少只是一个对象,但是对于整数命名的属性,数组确实有一些“有趣”和特殊的行为 . 以上将给你一个简单的对象 .

    编辑哦,你可能想要在数组中占到"holes":

    function toObject(arr) {
      var rv = {};
      for (var i = 0; i < arr.length; ++i)
        if (arr[i] !== undefined) rv[i] = arr[i];
      return rv;
    }
    

    在现代JavaScript运行时中,您可以使用 .reduce() 方法:

    var obj = arr.reduce(function(acc, cur, i) {
      acc[i] = cur;
      return acc;
    }, {});
    

    那个也避免了数组中的"holes",因为这就是 .reduce() 的工作方式 .

  • 3

    ECMAScript 6引入了易于聚合的Object.assign

    Object.assign()方法用于将所有可枚举的自有属性的值从一个或多个源对象复制到目标对象 . 它将返回目标对象 .

    Object.assign({}, ['a','b','c']); // {0:"a", 1:"b", 2:"c"}
    

    不会复制数组自己的 length 属性,因为它不可枚举 .

    此外,您可以使用ES6 spread syntax来实现相同的结果:

    { ...['a', 'b', 'c'] }
    
  • 1

    你可以使用累加器aka reduce .

    ['a','b','c'].reduce(function(result, item, index, array) {
      result[index] = item; //a, b, c
      return result;
    }, {}) //watch out the empty {}, which is passed as "result"
    

    传递一个空对象 {} 作为起点;然后"augment"该对象递增 . 在迭代结束时, result{"0": "a", "1": "b", "2": "c"}

    如果您的数组是一组键值对对象:

    [{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item) {
      var key = Object.keys(item)[0]; //first property: a, b, c
      result[key] = item[key];
      return result;
    }, {});
    

    将产生: {a: 1, b: 2, c: 3}

    为了完整起见, reduceRight 允许您以相反的顺序迭代数组:

    [{ a: 1},{ b: 2},{ c: 3}].reduceRight(/* same implementation as above */)
    

    将产生: {c:3, b:2, a:1}

    您的累加器可以是任何类型的特定用途 . 例如,为了在数组中交换对象的键和值,请传递 []

    [{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item, index) {
      var key = Object.keys(item)[0]; //first property: a, b, c
      var value = item[key];
      var obj = {};
      obj[value] = key;
      result.push(obj);
      return result;
    }, []); //an empty array
    

    将产生: [{1: "a"}, {2: "b"}, {3: "c"}]

    map 不同, reduce 不能用作1-1映射 . 您可以完全控制要包含或排除的项目 . 因此 reduce 允许你实现 filter 的功能,这使 reduce 非常灵活:

    [{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item, index) {
      if(index !== 0) { //skip the first item
        result.push(item);
      }
      return result;
    }, []); //an empty array
    

    将产生: [{2: "b"}, {3: "c"}]

    CautionreduceObject.keyECMA 5th edition 的一部分;你应该为不支持它们的浏览器提供polyfill(特别是IE8) .

    请参见Mozilla的默认实现 .

  • 1

    如果你正在使用jquery:

    $.extend({}, ['a', 'b', 'c']);
    
  • 22

    为了完整性,ECMAScript 2015(ES6)传播 . 将要求转换器(Babel)或至少运行ES6的环境 .

    { ...['a', 'b', 'c'] }
    
  • 15

    我可能会这样写(因为很少我手边没有下划线库):

    var _ = require('underscore');
    
    var a = [ 'a', 'b', 'c' ];
    var obj = _.extend({}, a);
    console.log(obj);
    // prints { '0': 'a', '1': 'b', '2': 'c' }
    
  • 261

    这是一个O(1)ES2015方法,只是为了完整性 .

    var arr = [1, 2, 3, 4, 5]; // array, already an object
    Object.setPrototypeOf(arr, Object.prototype); // now no longer an array, still an object
    
  • 5

    惊讶不见 -

    Object.assign({}, your_array)
    
  • 2
    Object.assign({}, ['one', 'two']); // {0: 'one', 1: 'two'}
    

    现代JavaScript中的简单方法是使用 Object.assign() ,除了将key:value从一个对象复制到另一个对象之外什么都不做 . 在我们的例子中, Array 将属性捐赠给新的 {} .

  • 2

    我们可以使用 Object.assignarray.reduce 函数将Array转换为Object .

    var arr = [{a:{b:1}},{c:{d:2}}] 
    var newObj = arr.reduce((a, b) => Object.assign(a, b), {})
    
    console.log(newObj)
    
  • 2

    我最终使用了对象扩展运算符,因为它是ECMAScript 2015(ES6)标准的一部分 .

    const array = ['a', 'b', 'c'];
    console.log({...array});
    // it outputs {0:'a', 1:'b', 2:'c'}
    

    以下以fiddle为例 .

  • 48

    五年后,有一个好方法:)

    Object.assign在ECMAScript 2015中引入 .

    Object.assign({}, ['a', 'b', 'c'])
    // {'0':'a', '1':'b', '2':'c'}
    
  • 2

    你可以使用传播运营商

    x = [1,2,3,10]
    {...x} // {0:1, 1:2, 2:3, 3:10}
    
  • 5

    使用javascript#forEach就可以做到这一点

    var result = {},
        attributes = ['a', 'b','c'];
    
    attributes.forEach(function(prop,index) {
      result[index] = prop;
    });
    

    使用ECMA6:

    attributes.forEach((prop,index)=>result[index] = prop);
    
  • 96

    快速而肮脏的一个:

    var obj = {},
      arr = ['a','b','c'],
      l = arr.length; 
    
    while( l && (obj[--l] = arr.pop() ) ){};
    
  • 222

    如果您使用的是ES6,则可以使用Object.assign和spread运算符

    { ...['a', 'b', 'c'] }
    

    如果您有嵌套数组

    var arr=[[1,2,3,4]]
    Object.assign(...arr.map(d => ({[d[0]]: d[1]})))
    
  • 3

    使用ES6 syntax你可以这样做:

    const arr = ['a', 'b', 'c'];
    const obj = {...arr}; // -> {0: "a", 1: "b", 2: "c"}
    
  • 430

    快速而肮脏的#2:

    var i = 0
      , s = {}
      , a = ['A', 'B', 'C'];
    
    while( a[i] ) { s[i] = a[i++] };
    
  • 1

    我只想用 Array.of() 来做这件事 . Array of has the ability to use it's context as a constructor.

    注2:功能是一种有意的通用工厂方法;它不要求它的值是Array构造函数 . 因此,它可以被传递给或者由可以使用单个数字参数调用的其他构造函数继承 .

    所以我们可以将 Array.of() 绑定到一个函数并生成一个像object这样的数组 .

    function dummy(){};
    var thingy = Array.of.apply(dummy,[1,2,3,4]);
    console.log(thingy);
    

    利用 Array.of() one can even do array sub-classing .

  • 1

    从Lodash 3.0.0开始,您可以使用_.toPlainObject

    var obj = _.toPlainObject(['a', 'b', 'c']);
    console.log(obj);
    
    <script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>
    
  • 6

    这允许您从数组生成一个对象,该对象具有您按照所需顺序定义的键 .

    Array.prototype.toObject = function(keys){
        var obj = {};
        var tmp = this; // we want the original array intact.
        if(keys.length == this.length){
            var c = this.length-1;
            while( c>=0 ){
                obj[ keys[ c ] ] = tmp[c];
                c--;
            }
        }
        return obj;
    };
    
    result = ["cheese","paint",14,8].toObject([0,"onion",4,99]);
    

    console.log(">>> :" + result.onion); 将输出"paint",该函数必须具有相等长度的数组,否则您将得到一个空对象 .

    这是一个更新的方法

    Array.prototype.toObject = function(keys){
        var obj = {};
        if( keys.length == this.length)
            while( keys.length )
                obj[ keys.pop() ] = this[ keys.length ];
        return obj;
    };
    
  • 14

    这是我刚写的一个递归函数 . 这很简单,效果很好 .

    // Convert array to object
    var convArrToObj = function(array){
        var thisEleObj = new Object();
        if(typeof array == "object"){
            for(var i in array){
                var thisEle = convArrToObj(array[i]);
                thisEleObj[i] = thisEle;
            }
        }else {
            thisEleObj = array;
        }
        return thisEleObj;
    }
    

    这是一个例子(jsFiddle):

    var array = new Array();
    array.a = 123;
    array.b = 234;
    array.c = 345;
    var array2 = new Array();
    array2.a = 321;
    array2.b = 432;
    array2.c = 543;
    var array3 = new Array();
    array3.a = 132;
    array3.b = 243;
    array3.c = 354;
    var array4 = new Array();
    array4.a = 312;
    array4.b = 423;
    array4.c = 534;
    var array5 = new Array();
    array5.a = 112;
    array5.b = 223;
    array5.c = 334;
    
    array.d = array2;
    array4.d = array5;
    array3.d = array4;
    array.e = array3;
    
    
    console.log(array);
    
    // Convert array to object
    var convArrToObj = function(array){
        var thisEleObj = new Object();
        if(typeof array == "object"){
            for(var i in array){
                var thisEle = convArrToObj(array[i]);
                thisEleObj[i] = thisEle;
            }
        }else {
            thisEleObj = array;
        }
        return thisEleObj;
    }
    console.log(convArrToObj(array));
    

    结果:
    Recursive Array to Object

  • 3
    .reduce((o,v,i)=>(o[i]=v,o), {})
    

    [文档]

    或者更详细

    var trAr2Obj = function (arr) {return arr.reduce((o,v,i)=>(o[i]=v,o), {});}
    

    要么

    var transposeAr2Obj = arr=>arr.reduce((o,v,i)=>(o[i]=v,o), {})
    

    最短的一个与香草JS

    JSON.stringify([["a", "X"], ["b", "Y"]].reduce((o,v,i)=>{return o[i]=v,o}, {}))
    => "{"0":["a","X"],"1":["b","Y"]}"
    

    一些更复杂的例子

    [["a", "X"], ["b", "Y"]].reduce((o,v,i)=>{return o[v[0]]=v.slice(1)[0],o}, {})
    => Object {a: "X", b: "Y"}
    

    更短(使用 function(e) {console.log(e); return e;} === (e)=>(console.log(e),e)

     nodejs
    > [[1, 2, 3], [3,4,5]].reduce((o,v,i)=>(o[v[0]]=v.slice(1),o), {})
    { '1': [ 2, 3 ], '3': [ 4, 5 ] }
    

    [/文档]

  • 42

    如果你可以使用 MapObject.assign ,那就很容易了 .

    创建一个数组:

    const languages = ['css', 'javascript', 'php', 'html'];
    

    下面创建一个索引为键的对象:

    Object.assign({}, languages)
    

    使用 Map 复制与上面相同的内容

    转换为基于索引的对象 {0 : 'css'} 等...

    const indexMap = new Map(languages.map((name, i) => [i, name] ));
    indexMap.get(1) // javascript
    

    转换为基于值的对象 {css : 'css is great'} 等...

    const valueMap = new Map(languages.map(name => [name, `${name} is great!`] ));
    valueMap.get('css') // css is great
    
  • 7

    FWIW,最近的另一种方法是使用新的 Object.fromEntriesObject.entries ,如下所示:

    const arr = ['a','b','c'];
    arr[-2] = 'd';
    arr.hello = 'e';
    arr.length = 17;
    const obj = Object.fromEntries(Object.entries(arr));
    

    ...允许避免将稀疏数组项存储为 undefinednull 并保留非索引(例如,非正整数/非数字)键 .

    但是,有人可能希望添加 arr.length ,因为这不包括在内:

    obj.length = arr.length;
    
  • 21

    你可以使用这样的函数:

    var toObject = function(array) {
        var o = {};
        for (var property in array) {
            if (String(property >>> 0) == property && property >>> 0 != 0xffffffff) {
                o[i] = array[i];
            }
        }
        return o;
    };
    

    这个应该更有效地处理稀疏数组 .

  • 1

    这是coffeescript的解决方案

    arrayToObj = (arr) ->
      obj = {}
      for v,i in arr
        obj[i] = v if v?
      obj
    
  • 14

    如果你使用angularjs你可以使用angular.extend,与$ .extend的jquery效果相同 .

    var newObj = {};
    angular.extend(newObj, ['a','b','c']);
    
  • 4

    它并不直接相关,但我来到这里寻找一个用于合并嵌套对象的衬垫,例如

    const nodes = {
        node1: {
            interfaces: {if1: {}, if2: {}}
        },
        node2: {
            interfaces: {if3: {}, if4: {}}
        },
        node3: {
            interfaces: {if5: {}, if6: {}}
        },
    }
    

    解决方案是使用reduce和object spread的组合:

    const allInterfaces = nodes => Object.keys(nodes).reduce((res, key) => ({...res, ...nodes[key].interfaces}), {})
    
  • 2
    let i = 0;
    let myArray = ["first", "second", "third", "fourth"];
    
    const arrayToObject = (arr) =>
        Object.assign({}, ...arr.map(item => ({[i++]: item})));
    
    console.log(arrayToObject(myArray));
    

    或者使用

    myArray = ["first", "second", "third", "fourth"]
    console.log({...myArray})
    

相关问题