2

This is my data with 5 arrays. What I wish to achieve is to combine id and name and the new array should have 5 different playname values. It can be in either an array or new key like 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",
  }

]

I am using lodash to try and achieve this but I am not able to get the data format I want using the code examples I have searched online.

This is my current code that I have tried that gives an array that is grouped by the ID.

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

The original data are not grouped by ID.

I am trying to get my data to look like this {"id": 1, "name": liquid, "playername": "GH", "playername2": "KuroKy" ....}

5 Answers 5

2

You could group by id and name properity and store the index for the same group.

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

Sign up to request clarification or add additional context in comments.

Comments

2

Group by a combination of id and name (${o.id}~~~${o.name}). Map the groups, extract the name and id from the 1st item, take the player names, and use _.mapKeys() to convert the indexes to object keys. Combine the id, name, and playername properties to a single object using spread.

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>

Comments

1

You can use reduce and Map. Here Map is used to keep track of number of palyername is used for particular id

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))

Comments

1

Just using using reduce to group the array into an object and Object.values to convert the object into an array.

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

Comments

0

The data could have been structured better. With the given structure, following code is one way to solve it.

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

With this code, you will have a new_data object of format

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.