Объединить массив объектов, объединить ключ с одинаковым значением и сохранить уникальное значение - PullRequest
2 голосов
/ 03 ноября 2019

Это мои данные с 5 массивами. Чего я хотел бы добиться, так это объединить id и name, и новый массив должен иметь 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": 1, "name": liquid, "playername": "GH", "playername2": "KuroKy" ....}

Ответы [ 5 ]

2 голосов
/ 03 ноября 2019

Группировка по комбинации id и name (${o.id}~~~${o.name}). Сопоставьте группы, извлеките name и id из 1-го элемента, возьмите имена игроков и используйте _.mapKeys() для преобразования индексов в ключи объектов. Объедините свойства id, name и playername в один объект, используя распространение.

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 голосов
/ 03 ноября 2019

Вы можете сгруппировать по id и name и сохранить индекс для той же группы.

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 голос
/ 03 ноября 2019

Просто используйте 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);
1 голос
/ 03 ноября 2019

Вы можете использовать reduce и Map. Здесь карта используется для отслеживания номера 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))
0 голосов
/ 03 ноября 2019

Данные могли бы быть лучше структурированы. С данной структурой следующий код является одним из способов ее решения.

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']
    }
}
...