Poi*_*nty 465

使用这样的函数:

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

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

编辑哦,你也可能想要在数组中考虑"漏洞":

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

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

var obj = arr.reduce(function(acc, cur, i) {
  acc[i] = cur;
  return acc;
}, {});
Run Code Online (Sandbox Code Playgroud)

那个也避免了数组中的"漏洞",因为这是.reduce()有效的.

  • 更简洁的方法来避免param重新分配`const obj = arr.reduce((obj,cur,i)=> {return {... obj,[i]:cur};},{});` (13认同)
  • @ m93a,它已经是一个对象。在JavaScript中,如果您不打算使用数字属性键和“ length”属性,那么实际上没有必要创建Array实例(`[]`)。 (2认同)
  • 没有显式返回的箭头+分解语法:`const obj = arr.reduce((obj,cur,i)=&gt;({{... obj,[i]:cur}),{});` (2认同)
  • 正如@VivekN 所说,每次都需要创建新对象吗?那么`arr.reduce((obj, cur, i) =&gt; (obj[i]=cur,obj), {});` 呢? (2认同)
  • 确实是@eugene_sunic,但是当我在2010年回答这个问题时,这种方法无法实现:) (2认同)
  • 正如 @miro 指出的那样,每次都创建一个新对象是没有必要的,而且实际上比操作创建的初始对象_慢得多_。在 1000 个元素的数组上运行 JSPerf 测试,每次创建一个新对象比改变现有对象慢 **1,000** 倍。https://jsperf.com/array-prototype-reduce-mutate-vs-intermediate-objects (2认同)

Ori*_*iol 383

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

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

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

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

此外,您可以使用ES6 扩展语法来实现相同的结果:

{ ...['a', 'b', 'c'] }
Run Code Online (Sandbox Code Playgroud)

  • Oriol,有没有办法设置固定键而不是 0 和 1? (15认同)
  • @Gel 使用“reduce”,例如:“arr.reduce((a, v) =&gt; ({ ...a, [v]: v}), {})” (9认同)
  • 这通常不是您想要的。通常您希望使用数组元素中的属性作为键。因此,减少就是你想要的。 (3认同)
  • 只是想指出 - 如果您已经拥有原始对象的排序属性数组,则使用 **spread** 运算符会将该数组直接转换为新对象:`{ ...[sortedArray]}` (2认同)
  • 如果我想要键不是 0,1,2 而是与值相同怎么办?就像:{a: 'a'} 我们该怎么做? (2认同)

rol*_*and 256

你可以使用累加器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"
Run Code Online (Sandbox Code Playgroud)

传递空物体{}作为起点; 然后逐渐"增加"该对象.在迭代结束时,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;
}, {});
Run Code Online (Sandbox Code Playgroud)

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

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

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

将产生: {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
Run Code Online (Sandbox Code Playgroud)

将产生: [{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
Run Code Online (Sandbox Code Playgroud)

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

警告:reduce并且Object.key是其中的一部分ECMA 5th edition; 你应该为不支持它们的浏览器提供polyfill(特别是IE8).

请参阅Mozilla的默认实现.

  • 当您使用对象映射并且需要删除其中一个键时,有助于维护 redux 存储 (2认同)

Max*_*Max 99

如果你正在使用jquery:

$.extend({}, ['a', 'b', 'c']);
Run Code Online (Sandbox Code Playgroud)

  • 奇怪的是,如果我放入一个Array变量,它会将每个字符放在一个单独的对象中:0:"a",1:",",2:"b"......所以它忽略了引号,但包括逗号.. . (4认同)
  • 有没有办法使用$ .extend同时以非数字方式通知键,即:对数组项进行计算? (3认同)

mcm*_*hav 57

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

console.log(
   { ...['a', 'b', 'c'] }
)
Run Code Online (Sandbox Code Playgroud)

  • 实际上,这在 ES2015 中也不是原生可用的。然而,它非常优雅。 (2认同)

gio*_*pds 54

这里没有多少人评论Object.fromEntries,我真的很喜欢它,因为它更干净并且可以轻松地与TypeScript一起使用,而不必过多担心泛型类型和东西。如果需要的话,它还允许使用map自定义键。map缺点:如果您想要自定义密钥,则需要额外的。例如:

const tags = [
  { name: 'AgeGroup', value: ageGroup },
  { name: 'ApparelTypes', value: apparelTypes },
  { name: 'Brand', value: brand },
  // ...
]

const objectTags = Object.fromEntries(tags.map((t) => [t.name, t.value]))

/*
{
  AgeGroup: 'Adult',
  Apparel: 'Creeper, Jacket'
  Brand: '',
  // ...
}
*/
Run Code Online (Sandbox Code Playgroud)


Dav*_*son 46

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

var _ = require('underscore');

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

  • 此问题没有下划线标记,您还假设node.js或require库. (14认同)
  • 下划线在客户端和服务器上都很常见.它假设为Backbone.js,可能是最常用的实用程序库.话虽这么说,我包括了要求线,以明确我使用的是库.没有用于描述"将underscore.js添加到您的页面"的1-liner,因此浏览器环境需要一些翻译 (10认同)
  • 你对我的回复进行了投票,但没有评论?我的回答是正确和经过测试的.有什么异议? (9认同)
  • 不过,如果你使用的是undserscore,那么简单的`obj = _.extend({},a);`就可以了.另外,如果你在迭代数组,我会说`_.each`比`_.map`更合适.总而言之,这在几个层面上都不是一个好的答案. (6认同)
  • "你必须回答而不提及下划线或者破折号",人们非常讨厌.可以说你必须在不提及标准库的情况下回答C++问题.如果不能选择下划线或者破折号,那么OP应该提到这一点. (4认同)
  • @CharlieMartin这个类比是完全有缺陷的,因为lodash,下划线和jQuery不是"标准库",并且在大量的JavaScript用例中,添加库会直接影响最终用户,而这一点不应该是出于微不足道的原因. (3认同)

Ben*_*aum 26

这是一个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
Run Code Online (Sandbox Code Playgroud)


Wyl*_*udd 23

惊讶不见 -

Object.assign({}, your_array)
Run Code Online (Sandbox Code Playgroud)


KAR*_*N.A 21

我们可以使用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)
Run Code Online (Sandbox Code Playgroud)


Joh*_*rek 18

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

// 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' }
}
Run Code Online (Sandbox Code Playgroud)

用:

const result = arr.reduce((obj, cur) => ({...obj, [cur.sid]: cur}), {})
Run Code Online (Sandbox Code Playgroud)


小智 17

Object.assign({}, ['one', 'two']); // {0: 'one', 1: 'two'}
Run Code Online (Sandbox Code Playgroud)

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


loc*_*ton 17

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

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

以下面的小提琴为例.


Mar*_* An 16

如果您的数组包含2 元素数组,其中第一个元素是键,第二个元素是值,您可以使用 轻松转换为对象reduce

[
  ["key1","value1"], 
  ["key2", "value2"], 
  ["key3", "value3"]
]
.reduce((acc, [key, value])=>({...acc, [key]: value}), {});
Run Code Online (Sandbox Code Playgroud)

结果:

{  
  key1: 'value1',   
  key2: 'value2', 
  key3: 'value3'  
}  
Run Code Online (Sandbox Code Playgroud)


Pau*_*per 10

五年后,有一个很好的方式:)

Object.assign 在ECMAScript 2015中引入.

Object.assign({}, ['a', 'b', 'c'])
// {'0':'a', '1':'b', '2':'c'}
Run Code Online (Sandbox Code Playgroud)


RIY*_*HAN 9

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

var result = {},
    attributes = ['a', 'b','c'];

attributes.forEach(function(prop,index) {
  result[index] = prop;
});
Run Code Online (Sandbox Code Playgroud)

使用ECMA6:

attributes.forEach((prop,index)=>result[index] = prop);
Run Code Online (Sandbox Code Playgroud)


mur*_*a k 9

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

{ ...['a', 'b', 'c'] }
Run Code Online (Sandbox Code Playgroud)

如果您有嵌套数组

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


小智 9

你可以使用传播运营商

x = [1,2,3,10]
{...x} // {0:1, 1:2, 2:3, 3:10}
Run Code Online (Sandbox Code Playgroud)


Ole*_*leb 9

使用ES6语法,您可以执行以下操作:

const arr = ['a', 'b', 'c'];
const obj = {...arr}; // -> {0: "a", 1: "b", 2: "c"} 
Run Code Online (Sandbox Code Playgroud)


Bry*_*nid 9

最短的答案:(使用解构)

const obj = { ...input }
Run Code Online (Sandbox Code Playgroud)

例子:

const inputArray = ["a", "b", "c"]
const outputObj = { ...inputArray }
Run Code Online (Sandbox Code Playgroud)


Bre*_*mir 8

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));
Run Code Online (Sandbox Code Playgroud)

...这可以避免将稀疏数组项存储为undefined或,null并保留非索引键(例如,非正整数/非数字键)。

arr.length但是,不妨增加一点,因为其中不包括:

obj.length = arr.length;
Run Code Online (Sandbox Code Playgroud)


San*_*Ali 8

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

var arr = ["One", "Two", 3];
var obj = {...arr};
console.log(obj);
Run Code Online (Sandbox Code Playgroud)


小智 7

为什么没有人尝试这个?在 ES6 中

let arr = ['a','b','c']
let {...obj} = arr
console.log(obj) //  {0: 'a', 1: 'b', 2: 'c'}
Run Code Online (Sandbox Code Playgroud)
let {...obj2} = ['a','b','c']
console.log(obj2) //  {0: 'a', 1: 'b', 2: 'c'}
Run Code Online (Sandbox Code Playgroud)

是很简单的方法吗?

  • 您不仅可以批评其他答案没有尝试某些东西,还可以使用“扩展语法”解释您的答案有哪些优点或者它与最佳答案有何不同。提示:请参阅 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#rest_property。 (10认同)

lor*_*del 6

又快又脏#2:

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

while( i < a.length ) { s[i] = a[i++] };
Run Code Online (Sandbox Code Playgroud)

  • 个人偏好在下一行以逗号开头。我发现这个符号更容易阅读。 (3认同)
  • 如果数组包含假值,循环将停止。你应该检查 `i &lt; a.length` 而不是 `a[i]`。 (2认同)

Ali*_*eza 6

更多浏览器支持更灵活的方法是使用普通循环,例如:

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

for (let i=0; i<arr.length; i++) {
   obj[i] = arr[i];
}
Run Code Online (Sandbox Code Playgroud)

但现代的方式也可以使用扩展运算符,例如:

{...arr}
Run Code Online (Sandbox Code Playgroud)

对象分配

Object.assign({}, ['a', 'b', 'c']);
Run Code Online (Sandbox Code Playgroud)

两者都会返回

{0: "a", 1: "b", 2: "c"}
Run Code Online (Sandbox Code Playgroud)


Mic*_*Mic 5

快速而肮脏的一个:

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

while( l && (obj[--l] = arr.pop() ) ){};
Run Code Online (Sandbox Code Playgroud)

  • @Qix,尼斯缩短 (2认同)

Mar*_*lin 5

一种将项目数组快速转换为对象的简单而厚脸皮的方法

function arrayToObject( srcArray ){
    return  JSON.parse( JSON.stringify( srcArray ) );
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它......

var p = [0,2,3,'pork','pie',6];
obj = new arrayToObject( p );
console.log( obj[3], obj[4] )
// expecting `pork pie`
Run Code Online (Sandbox Code Playgroud)

输出:

pork pie
Run Code Online (Sandbox Code Playgroud)

检查类型:

typeof obj
"object"
Run Code Online (Sandbox Code Playgroud)

如果没有原型方法,事情就不会完整

Array.prototype.toObject =function(){
    return  JSON.parse( JSON.stringify( this ) );
}
Run Code Online (Sandbox Code Playgroud)

使用类似:

var q = [0,2,3,'cheese','whizz',6];
obj = q.toObject();
console.log( obj[3], obj[4] )
// expecting `cheese whizz`
Run Code Online (Sandbox Code Playgroud)

输出:

cheese whizz
Run Code Online (Sandbox Code Playgroud)

*注意没有命名例程,所以如果你想有特定的名字,那么你需要继续使用下面的现有方法。


旧方法

这允许您从数组中生成一个对象,其中包含您按照所需顺序定义的键。

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]);
Run Code Online (Sandbox Code Playgroud)

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;
};
Run Code Online (Sandbox Code Playgroud)