合并对象数组,合并具有相同值的键并保留唯一值

时间:2019-11-03 09:46:15

标签: javascript lodash

这是我的5个数组的数据。我希望实现的是结合idname,新数组应该具有5个不同的播放名称值。它可以位于数组中,也可以位于诸如playername1之类的新键中。

[
  {
    "id": 1,
    "name": "Liquid",
    "playername": "GH",
  },
  {
    "id": 1,
    "name": "Liquid",
    "playername": "KuroKy",
  },
  {
    "id": 1,
    "name": "Liquid",
    "playername": "Miracle",
  },
  {
    "id": 1,
    "name": "Liquid",
    "playername": "w33",
  },
  {
    "id": 1,
    "name": "Liquid",
    "playername": "Mind-Control",
  }

]

我正在使用lodash尝试实现这一目标,但是我无法使用在线搜索的代码示例来获取所需的数据格式。

这是我目前尝试使用的代码,该代码给出了按ID分组的数组。

    _.forOwn(this.state.teamsData, function(value, key) {
      console.log(value);
    });

原始数据未按ID分组。

我正在尝试使数据看起来像这样{"id": 1, "name": liquid, "playername": "GH", "playername2": "KuroKy" ....}

5 个答案:

答案 0 :(得分:2)

您可以按idname的正确性进行分组,并存储同一组的索引。

var data = [{ id: 1, name: "Liquid", playername: "GH" }, { id: 1, name: "Liquid", playername: "KuroKy" }, { id: 1, name: "Liquid", playername: "Miracle" }, { id: 1, name: "Liquid", playername: "w33" }, { id: 1, name: "Liquid", playername: "Mind-Control" }],
    result = Object
        .values(data.reduce((r, { id, name, playername }) => {
            var key = [id, name].join('|');
            r[key] = r[key] || { data: { id, name }, index: 0 };
            r[key].data['playername' + (r[key].index++ || '')] = playername;
            return r;
        }, {}))
        .map(({ data }) => data);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:2)

idname${o.id}~~~${o.name})的组合进行分组。映射组,从第一项中提取nameid,获取播放器名称,然后使用_.mapKeys()将索引转换为对象键。使用传播将idnameplayername属性组合到单个对象。

const teamsData = [{"id":1,"name":"Liquid","playername":"GH"},{"id":1,"name":"Liquid","playername":"KuroKy"},{"id":1,"name":"Liquid","playername":"Miracle"},{"id":1,"name":"Liquid","playername":"w33"},{"id":1,"name":"Liquid","playername":"Mind-Control"}]

const result = _(teamsData)
  .groupBy(o => `${o.id}~~~${o.name}`) // group by id and name
  .map(group => ({ // map the groups
    ..._.pick(_.head(group), ['id', 'name']), // take id and name from 1st item
    ..._.mapKeys(_.map(group, 'playername'), // extract the player names
      (v, k) => `playername${+k > 0 ? +k + 1 : ''}` // create the keys
    )
  }))
  .value()
  
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

答案 2 :(得分:1)

您可以使用reduceMap。这里的Map用于跟踪特定ID的palyername的数量

const arr = [{"id":1,"name":"Liquid","playername":"GH"},{"id":1,"name":"Liquid","playername":"KuroKy"},{"id":1,"name":"Liquid","playername":"Miracle"},{"id":1,"name":"Liquid","playername":"w33"},{"id":1,"name":"Liquid","playername":"Mind-Control"}]

let groupData = (arr) => {
  let mapper = new Map()
  return Object.values(arr.reduce((op,{id, name, playername }) => {
    mapper.set(id, ( mapper.get(id) || 0) + 1 )
    let key = mapper.get(id)
    op[id] = op[id] || { id, name }
    op[id][`playername${key}`] = playername
    return op
  },{}))
}

console.log(groupData(arr))

答案 3 :(得分:1)

只需使用reduce将数组分组为对象,然后使用Object.values将对象转换为数组。

let list = [
{"id": 1,"name": "Liquid","playername": "GH",},
{"id": 2,"name": "Solid","playername": "KuroKy",},
{"id": 1,"name": "Liquid","playername": "Miracle",},
{"id": 1,"name": "Liquid","playername": "w33",},
{"id": 2,"name": "Solid","playername": "Mind-Control",}
];

let counter = {};
let result = Object.values(list.reduce((c, v) => {
  if (!c[v.id]) {
    counter[v.id] = 0;
    c[v.id] = {...v};
  } else c[v.id]["playername" + ++counter[v.id]] = v.playername;
  return c;
}, {}));


console.log(result);

答案 4 :(得分:0)

本来可以更好地组织数据。对于给定的结构,以下代码是解决问题的一种方法。

let data = [
    {"id": 1,"name": "Liquid","playername": "GH",},
    {"id": 2,"name": "Solid","playername": "KuroKy",},
    {"id": 1,"name": "Liquid","playername": "Miracle",},
    {"id": 1,"name": "Liquid","playername": "w33",},
    {"id": 2,"name": "Solid","playername": "Mind-Control",}
]; // Your data

let new_data = {}; // New structured data

data.map(function(data_object) {
    let team = new_data['id'+data_object.id];

    if(team==null) {
          // Creates a new object in new_data if an object
          // for the id does not exists.
          new_data['id'+data_object.id] = team = {};
          team.players = [];
    }
    team.id = data_object.id;
    team.name = data_object.name;
    team.players.push(data_object.playername);
});

console.log(new_data);

使用此代码,您将拥有一个new_data格式的对象

{
    id1 : {
           id : 1,
           name : Liquid,
           players : ['GH', 'Miracle', 'w33']
    },
    id2 : {
           id : 2,
           name : Solid,
           players : ['Kuroky', 'Mind-control']
    }
}