如何将数组转换为对象?

826
什么是最好的转换方式:
['a','b','c']

到:

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

2
如果其他人正在寻找Lodash解决方案,请考虑使用_.keyBy(以前称为_.indexBy):https://lodash.com/docs#keyBy - 2540625
1
这有点令人困惑,因为数组已经是对象了,但我猜问题的重点是将数组 异类对象转换为普通对象 - Oriol
3
使用 Lodash 来简单实现这个操作的方法是 _.toPlainObject。例如:var myObj = _.toPlainObject(myArr) - julian soro
46个回答

2
最简单的方法是按照以下步骤进行操作:
const arr = ['a','b','c'];
let obj = {}

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

这种方式只有在它是数组的情况下才会运行,但是你可以使用 let 全局对象变量或不使用,这取决于你自己,如果你不使用 let,只需执行 Object.assign({}, arr)。


这是与顶部答案提供的相同解决方案。 - Cristik

2

如果您喜欢简洁明了的代码,并且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});
}, {})

2

You could use a function like this:

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

这个程序应更高效地处理稀疏数组。

2

虽然与此无直接关系,但我在这里搜索一行代码来合并嵌套对象,例如

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

解决方法是使用reduce和对象展开运算符的组合:
const allInterfaces = nodes => Object.keys(nodes).reduce((res, key) => ({...res, ...nodes[key].interfaces}), {})

2
另外,Object.fromEntries(Object.entries(nodes).map(([key, value] => [key, value.interfaces])) - Jeff Fairley

1
以下方法将把数组转换为具有特定给定键的对象。
    /**
     * 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'}}

如果方法没有提供参数作为关键字

i.e. [{name: 'test'}, {name: 'test1'}].ArrayToObject();

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

1
这是一份 Coffeescript 的解决方案。
arrayToObj = (arr) ->
  obj = {}
  for v,i in arr
    obj[i] = v if v?
  obj

7
CoffeeScript是什么?我们在谈论JavaScript! :D - m93a
2
这是一种编译成JavaScript的小语言 :) - David
6
哼,它使用了奇怪的符号表示法。我更喜欢普通的 JS。 - m93a
2
@David 你可以将整个for循环写在一行上,使整个代码只有3行。 :) 示例:obj[i] = v for v,i in arr when v? - XåpplI'-I0llwlg'I -

1
如果您正在使用angularjs,您可以使用angular.extend,它与jquery的$.extend具有相同的效果。
var newObj = {};
angular.extend(newObj, ['a','b','c']);

0

我会使用下划线来实现这个,但如果不可用,我会降级到使用 reduce 函数,并将初始值设为空对象 {}

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

现在大多数浏览器都应该可以使用reduce函数,详情请参见MDN


相同的解决方案已经在第二个最佳答案中提供。 - Cristik
@Cristik 现在是这样,但当时不是。现在最烦人的趋势之一是在没有提供来源的情况下从底部答案复制代码片段到顶部答案。 - Meitham
在发表评论之前,我查看了修订历史记录,它显示引入 reduce() 的编辑是在2014年3月12日添加的,早于您的回答发布时间。 - Cristik

0

相同的解决方案已经在第二个最佳答案中提供。 - Cristik

0

Typescript解决方案:

export const toMap = (errors: ResponseError[]) => {
  const errorMap: Record<string, string> = {};
  errors.forEach(({ field, message }) => {
    errorMap[field] = message;
  });
  return errorMap;
};

export type FieldError = {
  field: string;
  message: string;
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接