将数组转换为对象

时间:2010-11-18 14:22:35

标签: javascript arrays node.js object

转换的最佳方式是什么:

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

为:

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

47 个答案:

答案 0 :(得分:441)

使用这样的函数:

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

那个也避免了数组中的“漏洞”,因为这就是.reduce()的工作原理。

答案 1 :(得分:290)

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 :(得分:230)

您可以使用累加器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不同,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"}]

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

请参阅Mozilla的默认实施。

答案 3 :(得分:97)

如果你正在使用jquery:

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

答案 4 :(得分:49)

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

synchronizeFile

答案 5 :(得分:42)

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

var _ = require('underscore');

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

答案 6 :(得分:22)

这是一个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

答案 7 :(得分:21)

很惊讶不去看 -

Object.assign({}, your_array)

答案 8 :(得分:15)

我们可以使用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)

答案 9 :(得分:15)

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

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

答案 10 :(得分:14)

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

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

以下列fiddle为例。

答案 11 :(得分:13)

如果您想使用迭代对象的属性之一作为键,例如:

// from:
const arr = [
    {
        sid: 123,
        name: 'aaa'
    },
    {
        sid: 456,
        name: 'bbb'
    },
    {
        sid: 789,
        name: 'ccc'
    }
];
// to:
{
  '123': { sid: 123, name: 'aaa' },
  '456': { sid: 456, name: 'bbb' },
  '789': { sid: 789, name: 'ccc' }
}

使用:

const result = arr.reduce((obj, cur) => ({...obj, [cur.sid]: cur}), {})

答案 12 :(得分:8)

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

Object.assign在ECMAScript 2015中被引入。

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

答案 13 :(得分:7)

您可以使用点差运算符

swing

答案 14 :(得分:6)

如果您正在使用ES6,则可以使用Object.assign和传播运算符

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

如果您有嵌套数组,如

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

答案 15 :(得分: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 :(得分:6)

最简单的方法是使用展开运算符。

var arr = ["One", "Two", 3];
var obj = {...arr};
console.log(obj);

答案 17 :(得分:5)

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;

答案 18 :(得分:5)

快速而肮脏的一个:

var obj = {},
  arr = ['a','b','c'],
  l = arr.length; 

while( l && (obj[--l] = arr.pop() ) ){};

答案 19 :(得分:4)

对于ES2016,对象的散布运算符。注意:这是 之后的ES6,因此需要对Transpiler进行调整。

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

答案 20 :(得分:3)

从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)

我会简单地使用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

答案 22 :(得分:3)

快速而肮脏的#2:

var i = 0
  , s = {}
  , a = ['A', 'B', 'C'];

while( a[i] ) { s[i] = a[i++] };

答案 23 :(得分:2)

.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 ] }

[/文档]

答案 24 :(得分:2)

如果您可以使用192.168.2.100engine = create_engine('mysql://root:1111@192.168.2.100:3305/vatic') ,那就很容易了。

创建一个数组:

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

答案 25 :(得分:2)

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

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

答案 26 :(得分:2)

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

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

答案 27 :(得分:1)

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

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

答案 28 :(得分:1)

你可以使用这样的函数:

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)

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

'1'

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

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

答案 30 :(得分:1)

支持更多浏览器更灵活的方式是使用常规的循环,例如:

const arr = ['a', 'b', 'c'],
obj = {};

for (let i=0; i<arr.length; i++) {
   obj[i] = arr[i];
}

但是现代方式也可以使用 spread运算符,例如:

{...arr}

对象分配

Object.assign({}, ['a', 'b', 'c']);

双方都会返回

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

答案 31 :(得分:1)

ES5-解决方案:

使用 Array 原型函数'push''apply',您可以使用数组元素填充对象。

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

答案 32 :(得分:1)

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

答案 33 :(得分:1)

这是coffeescript的解决方案

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

答案 34 :(得分:0)

如果有人在寻找 Typescript 方法,我写了这个:

const arrayToObject = <T extends Record<K, any>, K extends keyof any>(
  array: T[] = [],
  getKey: (item: T) => K,
) =>
  array.reduce((obj, cur) => {
    const key = getKey(cur)
    return ({...obj, [key]: cur})
  }, {} as Record<K, T>)

它将:

  1. 强制第一个参数为对象数组
  2. 帮助选择键
  3. 强制该键为所有数组项的键

示例:

// from:
const array = [
    { sid: 123, name: 'aaa', extra: 1 },
    { sid: 456, name: 'bbb' },
    { sid: 789, name: 'ccc' }
];
// to:
{
  '123': { sid: 123, name: 'aaa' },
  '456': { sid: 456, name: 'bbb' },
  '789': { sid: 789, name: 'ccc' }
}

用法:

const obj = arrayToObject(array, item => item.sid) // ok
const obj = arrayToObject(array, item => item.extra) // error

https://www.typescriptlang.org/play?#code/MYewdgzgLgBAhgJwXAngFRAeQEYCsCmwsAvDADxoz4AeU+YAJhDAEqEgINkDSANPGBQA+ftyq16TGAGt8KEADMBwgBQBYAFAx4SVAC4YaANoBdGKVO9N2gOb4o3OQZUBLOgFsDaAJTmhMPk1fYiFrHWQUADoEfAYAV2B8FRUQPH5gOIRg-wBvMO1QSFhZFHMYOwc5FQys-JgYqEywGBUcyPbU3H4jEpMDGoBfbzCB-hyB+GY2UE4efjQhYY1NQuhw1DKjHJgXBgMARgAmAGYAFhhRmG3dgwAiI+Pb-jgoOAMAcn33i7GdvZhDhcTCtwGtOmVEBEMDgCEQVJDUPx8AAbPxUZGRXZLVYgZH4SLIkA2VqdIZAA

答案 35 :(得分:0)

使用javascript reduce很容易:

["a", "b", "c", "d"].reduce(function(previousValue, currentValue, index) { 
   previousValue[index] = currentValue; 
   return previousValue;
}, 
{}
);

您可以查看Array.prototype.reduce(),https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

答案 36 :(得分:0)

尝试使用反射将数组项复制到对象。

var arr =['aa:23','bb:44','cc:55']
    var obj ={}
    arr.forEach(e => {
        var ee = e.split(':')
        Reflect.set(obj,ee[0],ee[1])
    });
    console.log(obj) // { aa: '23', bb: '44', cc: '55' }

答案 37 :(得分:0)

执行此操作的最简单方法如下:

const arr = ['a','b','c'];
let obj = {}

function ConvertArr(arr) { 
 if (typeof(arr) === 'array') {
 Object.assign(obj, arr);
}

这样,它仅在是数组时才运行,但是,可以使用let全局对象变量来运行它,也可以不运行,这取决于您,如果不使用let来运行,只需执行Object.assign({},arr) 。

答案 38 :(得分:0)

下面的方法会将数组转换为具有特定给定键的对象。

    /**
     * Converts array to object
     * @param  {Array} array
     * @param  {string} key (optional)
     */
    Array.prototype.ArrayToObject = function(key) {
       const array = this;
       const obj = {};

       array.forEach((element, index) => {
           if(!key) {
              obj[index] = element;
           } else if ((element && typeof element == 'object' && element[key])) {
              obj[element[key]] = element;
           }
       });
    return obj;
    }

对于前 -

[{name:'test'},{name:'test1'}]。ArrayToObject('name');

会给出

{test: {name: 'test'}, test1: {name: 'test1'}}

并且incase键不作为方法

的参数提供
i.e. [{name: 'test'}, {name: 'test1'}].ArrayToObject();

会给出

{0: {name: 'test'}, 1: {name: 'test1'}}

答案 39 :(得分:0)

我会使用下划线,但如果那不可用,那么我会下拉到使用带有空对象{}初始值的reduce

>>> ['a', 'b', 'c'].reduce(function(p, c, i) {p[i] = c; return p}, {})
Object { 0="a", 1="b", 2="c"}

reduce应该在今天的大多数浏览器中广泛使用,请参阅MDN

答案 40 :(得分:0)

初始数组并将转换为带有键的对象,这将是数组的唯一元素,键值将是特定键重复的次数

var jsTechs = ['angular', 'react', 'ember', 'vanilaJS', 'ember', 'angular', 'react', 'ember', 'vanilaJS', 'angular', 'react', 'ember', 'vanilaJS', 'ember', 'angular', 'react', 'ember', 'vanilaJS', 'ember', 'angular', 'react', 'ember', 'vanilaJS', 'ember', 'react', 'react', 'vanilaJS', 'react', 'vanilaJS', 'vanilaJS']

var initialValue = {
  java : 4
}

var reducerFunc = function reducerFunc (initObj, jsLib) {
  if (!initObj[jsLib]) {
    initObj[jsLib] = 1
  } else {
    initObj[jsLib] += 1
  }
  return initObj
}
var finalResult = jsTechs.reduce(reducerFunc, initialValue)
console.log(finalResult)

答案 41 :(得分:0)

如果你喜欢oneliners,IE8不再是问题(应该是这样)

['a','b','c'].reduce((m,e,i) => Object.assign(m, {[i]: e}), {});

继续在浏览器控制台上试试

这样更加冗长:

['a','b','c'].reduce(function(memo,elm,idx) {
    return Object.assign(memo, {[idx]: elm});
}, {});

但仍然排除了IE8。如果IE8是必须的,那么你可以像这样使用lodash / underscore:

_.reduce(['a','b','c'], function(memo,elm,idx) {
    return Object.assign(memo, {[idx]: elm});
}, {})

答案 42 :(得分:-1)

也许您也想将数组值用作对象键

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

答案 43 :(得分:-1)

使用javascript lodash库。有一个简单的方法 _.mapKeys(object, [iteratee=_.identity])  可以进行转换。

答案 44 :(得分:-1)

我的版本数组到JS中的json。 Jusy复制/粘贴并使用它。这不是很棒吗?我喜欢我在StackOverflow上找到的这类函数。

function array2json(arr) {
    var parts = [];
    var is_list = (Object.prototype.toString.apply(arr) === '[object Array]');

    for(var key in arr) {
        var value = arr[key];
        if(typeof value == "object") { //Custom handling for arrays
            if(is_list) parts.push(array2json(value)); /* :RECURSION: */
            else parts[key] = array2json(value); /* :RECURSION: */
        } else {
            var str = "";
            if(!is_list) str = '"' + key + '":';

            //Custom handling for multiple data types
            if(typeof value == "number") str += value; //Numbers
            else if(value === false) str += 'false'; //The booleans
            else if(value === true) str += 'true';
            else str += '"' + value + '"'; //All other things
            // :TODO: Is there any more datatype we should be in the lookout for? (Functions?)

            parts.push(str);
        }
    }
    var json = parts.join(",");

    if(is_list) return '[' + json + ']';//Return numerical JSON
    return '{' + json + '}';//Return associative JSON
}

答案 45 :(得分:-3)

var result = containers.Where(x => x.Id IN containerIds);

答案 46 :(得分:-5)

更多OO方法:

Array.prototype.toObject = function() {
 var Obj={};

 for(var i in this) {
  if(typeof this[i] != "function") {
   //Logic here
   Obj[i]=this[i];
  }
 }

 return Obj;
}