使用类似于 Array.prototype.map() 的方法将数组转换为键值对象

Converting an array to a key-value object using a method similar to Array.prototype.map()?

本文关键字:转换 数组 键值 对象 键值对 方法 Array 类似于 prototype map      更新时间:2023-09-26

是否有任何类似于Array.prototype.mapArray方法获取数组并将其转换为键值对象?

下面是一个示例:

var people = [{name: 'person1', tableId: 1}, {name: 'person2', tableId: 2}];
var table = [{id:1, shape:2, title: 'table1'}, {id:2, shape:4, title: 'table2'}];

我想创建一个表人对象,其中键将是一个 id,值将是具有相关 tableId 的所有人。

输出的示例如下:

var output = {
  1: [{name: 'person1', tableId: 1}, <more people>], 
  2: [{name: 'person2', tableId: 2}}, <more people>]
};

output将是一个键值对象。键是 tableId,值是人员数组。一个人有更多的信息(除了名称和 tableId - 这只是一个简单的例子(。

现在最简单的方法是:

var output = {};
for(var i = 0 ; i < table.length ; i++)
{
   output[table.id] = getPeopleThatSitInTable(table.id); // will return an array
}

有没有像这样的方法:

table.keyValueMapObject(function(item){
  return { key: item.id, value: getPeopleThatSitInTable(item.id) }
});

此方法将在幕后创建一个对象,根据键和值填充它并返回对象?

不是在寻找类似的东西:

var obj = {}; // declaring an object
// loop somehow and fill obj(for'foreach'map'reduce etc.)

因为使用for以"最好的方式"做同样的事情。

正在寻找类似的东西:

var obj = table.methodName(filterFunction)

检查 _.groupBy(( 源。它完全符合您的要求。

我认为在这种情况下最相关的数组方法是reduce。虽然它没有多大帮助,但您将表简化为键值对象:

var result = table.reduce(function(result, entry) {
    result[entry.id] = people.filter(function(person) { // pretty inefficient
        return person.tableId === entry.id;
    });
    return result;
}, {}); // initial key-value object

但实际上这种reduce的使用有点荒谬,因为回调并没有真正结合两个值。它只是修改和传递初始对象。虽然它明确了意图,但它与使用 forEach 相同:

var result = {}; // initial key-value object
table.forEach(function(entry) {
    result[entry.id] = people.filter(function(person) { // pretty inefficient
        return person.tableId === entry.id;
    });
});

即便如此,过滤整个people阵列的效率也非常低。您应该只迭代一次。

var result = {}; // initial key-value object
table.forEach(function(entry) {
    result[entry.id] = [];
});
people.forEach(function(person) {
    result[person.tableId].push(person);
});

我认为没有太大的简化潜力。

当然,借助 Object.assign、扩展运算符、数组推导、计算属性名称、对象解构和箭头函数的强大功能,您可以按如下方式编写它:

var result = Object.assign({}, ...[{
    [id]: people.filter(
        ({tableId}) => tableId === id
    )
} for({id} of table)]);

但它几乎与第一个版本相同。同样,它效率低下。而且它目前似乎只在火狐中工作。

我想短期内不会有原生的等价物。

您可以使用forEach通过基于tableId筛选人员来迭代表并构造表人对象,如下所示:

"use strict";
var people = [{name: 'person1', tableId: 1}, {name: 'person2', tableId: 2}];
var table = [{id:1, shape:2, title: 'table1'}, {id:2, shape:4, title: 'table2'}];
var tablePeopleObj = {};
table.forEach(function (tableItem) {
  tablePeopleObj[tableItem.id] = getPeople(tableItem.id);
});

function getPeople(tableId) {
  return people.filter(function function_name (person) {
    return person.tableId == tableId;
  });
}
console.log(tablePeopleObj);

下面使用Array.prototype.map,但可能不是你想要的。将其视为一个可能有用的使用示例:

var people = [{name: 'person1', tableId: 1}, {name: 'person2', tableId: 2}];
var obj = {};
people.map(function(v, i) {
  var key = v.tableId;
  if (!this.hasOwnProperty(key)) {
    this[key] = [];
  }
  this[key].push(v);
}, obj);