如何在数组中按值组织二维数组?

时间:2019-06-11 03:07:03

标签: javascript

我想组织一个二维数组。 数组的值是object,我想将值中的数据用作新对象/数组的键。

我拥有的数组:

let arr = [
  {name: 'Tom', class: A, sport: football},
  {name: 'Mary', class: C, sport: swimming},
  {name: 'Sam', class: B, sport: baseball},
  {name: 'Tom', class: A, sport: baseball},
  {name: 'Jim', class: B, sport: run},
  {name: 'Mary', class: C, sport: tennis}
]

我想要的结果

let result = [
  Tom: [{class: A, sport: football}, {class: A, sport: baseball}],
  Mary: [{class: C, sport: swimming}, {class: C, sport: tennis}],
  Sam: [{class: A, sport: baseball}],
  Jim: [{class: B, sport: run}]
]

没关系,结果与上面的略有不同。 我只想按名称组织数据并使其易于使用。

2 个答案:

答案 0 :(得分:2)

正如@Shidersz所指出的,由于与数组的定义背道而驰,因此无法获得插入的确切预期输出。

以下代码段应用了一个转换,该转换的输出是预期输出的略微修改版本,但满足了按名称组织数据的需求。

arr.reduce(function (a, e, i, l) {
  return Object.assign(a, {
    [ e.name ]: a[e.name] && a[e.name].concat(e) || [ e ]
  });
}, {});
{
  Jim: [
    {name: "Jim", class: "B", sport: "run"}
  ],
  Mary: [
    {name: "Mary", class: "C", sport: "swimming"},
    {name: "Mary", class: "C", sport: "tennis"}
  ],
  Sam: [
    {name: "Sam", class: "B", sport: "baseball"}
  ],
  Tom: [
    {name: "Tom", class: "A", sport: "football"},
    {name: "Tom", class: "A", sport: "baseball"}
  ]
}

或者,可以使用实用程序库来获得@Paul指出的类似转换

答案 1 :(得分:0)

这是使用groupby操作,然后将对象的值映射为不包括name属性的另一种方法。

let input = [
  {name: 'Tom',  class: 'A', sport: 'football'},
  {name: 'Mary', class: 'C', sport: 'swimming'},
  {name: 'Sam',  class: 'B', sport: 'baseball'},
  {name: 'Tom',  class: 'A', sport: 'baseball'},
  {name: 'Jim',  class: 'B', sport: 'run'},
  {name: 'Mary', class: 'C', sport: 'tennis'}
];

/**
 * group elements in an array by the result of some key function.
 * @param {array} arr The array to group.
 * @param {function} keyFn  the function returning the value to group on.
 */
function groupByKey(arr, keyFn) {
    const result = {};

    for(let a of arr) {
        const grouper = keyFn(a);
        if(grouper in result) result[grouper].push(a);
        else                  result[grouper] = [a];
    }
    return result;
}

/**
 * Map objects values, leaving the keys untouched.
 * @param {object} ob The object to have its values mapped.
 * @param {function} mapFn The function to perform the mapping.
 */
function mapValues(ob, mapFn){
    const result = {};

    for (let k of Object.keys(ob)) {
        result[k] = mapFn(ob[k]);
    }
    return result;
}

console.log(
    mapValues(
        groupByKey(input, x => x.name),
        x => x.map(y => ({class: y.class, sport: y.sport}))
    )
);