代码之家  ›  专栏  ›  技术社区  ›  David Hellsing

将数组转换为对象

  •  375
  • David Hellsing  · 技术社区  · 14 年前

    什么是最好的转换方式:

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

    致:

    {
      0: 'a',
      1: 'b',
      2: 'c'
    }
    
    42 回复  |  直到 6 年前
        1
  •  391
  •   itamar    6 年前

    ECMAScript 6引入了易填充的 Object.assign :

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

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

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

    另外,你可以使用ES6 spread syntax 为了达到同样的效果:

    { ...['a', 'b', 'c'] }
    
        2
  •  467
  •   Jordan Frankfurt Pointy    8 年前

    有这样的功能:

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

    您的数组已经或多或少只是一个对象,但是数组在整数命名属性方面确实有一些“有趣的”和特殊的行为。上面会给你一个简单的对象。

    编辑 哦,你可能还想解释数组中的“洞”:

    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;
    }, {});
    

    这个也避免了数组中的“洞”,因为这就是 .减少() 作品。

        3
  •  259
  •   roland    7 年前

    你可以用一个累加器 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"
    

    传递空对象 {} 作为一个起点;然后递增地“扩充”那个对象。 在迭代结束时, 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 , 减少 不能用作1-1映射。您可以完全控制要包含或排除的项。因此 减少 让你实现什么 filter 是的,这使得 减少 多才多艺:

    [{ 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"}]

    注意安全 : 减少 Object.key ECMA 5th edition ;您应该为不支持它们的浏览器(特别是IE8)提供polyfill。

    查看默认实现 Mozilla .

        4
  •  100
  •   Max    13 年前

    如果使用jquery:

    $.extend({}, ['a', 'b', 'c']);
    
        5
  •  57
  •   vsync    5 年前

    为了完整起见,ECMAScript 2015(ES6)正在传播。需要一个transpiler(巴别塔)或至少运行ES6的环境。

    console.log(
       { ...['a', 'b', 'c'] }
    )
        6
  •  46
  •   Prerna Jain    8 年前

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

    var _ = require('underscore');
    
    var a = [ 'a', 'b', 'c' ];
    var obj = _.extend({}, a);
    console.log(obj);
    // prints { '0': 'a', '1': 'b', '2': 'c' }
    
        7
  •  26
  •   Benjamin Gruenbaum    9 年前

    这里有一个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
    
        8
  •  23
  •   Wylliam Judd    8 年前

    惊讶地看不见-

    Object.assign({}, your_array)
    
        9
  •  21
  •   KARTHIKEYAN.A    7 年前

    我们可以利用 Object.assign array.reduce 函数将数组转换为对象。

    var arr = [{a:{b:1}},{c:{d:2}}] 
    var newObj = arr.reduce((a, b) => Object.assign(a, b), {})
    
    console.log(newObj)
        10
  •  17
  •   Paul Rooney    8 年前
    Object.assign({}, ['one', 'two']); // {0: 'one', 1: 'two'}
    

    在现代JavaScript中,使用 Object.assign() 这只会将key:value从一个对象复制到另一个对象。就我们而言, Array 捐赠财产给新的 {} .

        11
  •  17
  •   locropulenton    7 年前

    我最终使用了object spread操作符,因为它是ECMAScript 2015(ES6)标准的一部分。

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

    做了以下事情 fiddle 作为一个例子。

        12
  •  10
  •   Paul Draper    8 年前

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

    Object.assign 在ECMAScript 2015中引入。

    Object.assign({}, ['a', 'b', 'c'])
    // {'0':'a', '1':'b', '2':'c'}
    
        13
  •  9
  •   noel zubin    7 年前

    您可以使用spread运算符

    x = [1,2,3,10]
    {...x} // {0:1, 1:2, 2:3, 3:10}
    
        14
  •  9
  •   murthy naika k    7 年前

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

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

    如果有嵌套数组

    var arr=[[1,2,3,4]]
    Object.assign(...arr.map(d => ({[d[0]]: d[1]})))
    
        15
  •  9
  •   RIYAJ KHAN    6 年前

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

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

    使用ECMA6:

    attributes.forEach((prop,index)=>result[index] = prop);
    
        16
  •  9
  •   dman    5 年前

    对于ES2016,对象的spread运算符。注:这是 之后 ES6和so开卷机需要调整。

    const arr = ['a', 'b', 'c'];
    const obj = {...arr}; // -> {0: "a", 1: "b", 2: "c"} 
        17
  •  8
  •   Brett Zamir    6 年前

    FWIW,另一个最近的方法是使用新的 Object.fromEntries 随着 Object.entries 具体如下:

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

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

    不妨补充一点 arr.length 但是,由于这不包括:

    obj.length = arr.length;
    
        18
  •  5
  •   Mic    9 年前

    又快又脏的:

    var obj = {},
      arr = ['a','b','c'],
      l = arr.length; 
    
    while( l && (obj[--l] = arr.pop() ) ){};
    
        19
  •  4
  •   lordkrandel    12 年前

    又快又脏#2:

    var i = 0
      , s = {}
      , a = ['A', 'B', 'C'];
    
    while( a[i] ) { s[i] = a[i++] };
    
        20
  •  4
  •   acontell    8 年前

    从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>
        21
  •  3
  •   Mark Giblin    10 年前

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

    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;
    };
    
        22
  •  3
  •   JVE999    10 年前

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

    // 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

        23
  •  3
  •   test30    8 年前
    .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 ] }
    

    [/docs]

        24
  •  3
  •   Community CDub    7 年前

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

    注2:of函数是一个有意的通用工厂方法;它 不要求其此值为数组构造函数。 因此,它可以被其他构造函数传递或继承 可以用单个数值参数调用的。

    所以我们可以 数组,共() 生成一个类似数组的对象。

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

    利用 数组,共() one can even do array sub-classing .

        25
  •  3
  •   Shannon Hochkins    7 年前

    如果你能使用 Map Object.assign ,很简单。

    创建数组:

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

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

    Object.assign({}, languages)
    

    使用映射复制上述内容

    转换为基于索引的对象 {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
    
        26
  •  2
  •   Mahdi Bashirpour    6 年前

    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})
        27
  •  2
  •   SridharKritha    6 年前

    ES5-解决方案:

    使用 阵列 原型函数 '推' '应用' 可以用数组元素填充对象。

    var arr = ['a','b','c'];
    var obj = new Object();
    Array.prototype.push.apply(obj, arr);
    console.log(obj);    // { '0': 'a', '1': 'b', '2': 'c', length: 3 }
    console.log(obj[2]); // c
        28
  •  1
  •   Pablo Cabrera    14 年前

    您可以使用这样的函数:

    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;
    };
    

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

        29
  •  1
  •   David    12 年前

    这里有一个咖啡脚本的解决方案

    arrayToObj = (arr) ->
      obj = {}
      for v,i in arr
        obj[i] = v if v?
      obj
    
        30
  •  1
  •   Vicruz    10 年前

    如果您使用的是angularjs,那么可以使用angular.extend,与jquery的$.extend效果相同。

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