0

I am kind of new in programming world, please help me. Any help would be appreciated! I have an array with data like shown below. I have to make the data so that in every group only contains paired user_id in sequence. The paired user_id should be different if they are going to be paired.

  [
      {"user_id": 35, "group": "A"},
      {"user_id": 40, "group": "B"},
      {"user_id": 39, "group": "B"},
      {"user_id": 39, "group": "B"},
      {"user_id": 39, "group": "B"},
      {"user_id": 40, "group": "B"},
      {"user_id": 39, "group": "B"},
      {"user_id": 39, "group": "B"},
      {"user_id": 40, "group": "C"},
      {"user_id": 39, "group": "C"}
    ]

So the data will be like this:

The first item is removed because it doesn't has pair. The 5th and 6th items are removed because it has same user_ids with each other (user_id should be different if it is going to be paired).

[
  {"user_id": 35, "group": "A"}, <-- remove
  {"user_id": 40, "group": "B"},
  {"user_id": 39, "group": "B"},
  {"user_id": 39, "group": "B"}, <-- remove
  {"user_id": 39, "group": "B"}, <-- remove
  {"user_id": 40, "group": "B"},
  {"user_id": 39, "group": "B"},
  {"user_id": 39, "group": "B"}, <-- remove
  {"user_id": 40, "group": "B"}, <-- remove
  {"user_id": 40, "group": "C"},
  {"user_id": 39, "group": "C"}
]

So, the result would be:

[
  {"user_id": 40, "group": "B"},
  {"user_id": 39, "group": "B"},
  {"user_id": 40, "group": "B"},
  {"user_id": 39, "group": "B"},
  {"user_id": 40, "group": "C"},
  {"user_id": 39, "group": "C"}
]

What is the best way to achieve this (using splice method or create a new array and then push it, or another ways)?

Adam Azad
  • 11,171
  • 5
  • 29
  • 70

3 Answers3

1

You can do it like this:

for(var i = 0; arr.length > i;) {
  if (!arr[i+1] || arr[i].group != arr[i+1].group) {
    //arr[i] is last in the group
    arr.splice(i, 1);
  } else if (arr[i].user_id == arr[i+1].user_id || (arr[i-1] && arr[i].user_id == arr[i-1].user_id && arr[i].group == arr[i-1].group)) {
    //next or previous item have same id and group
    arr.splice(i, 1);
  } else {
    //arr[i] and arr[i+1] is a valid pair
    i += 2;
  }
}

var arr = [
  {"user_id": 35, "group": "A"}, //<-- remove
  {"user_id": 40, "group": "B"},
  {"user_id": 39, "group": "B"},
  {"user_id": 39, "group": "B"}, //<-- remove
  {"user_id": 39, "group": "B"}, //<-- remove
  {"user_id": 40, "group": "B"},
  {"user_id": 39, "group": "B"},
  {"user_id": 39, "group": "B"}, //<-- remove
  {"user_id": 40, "group": "B"}, //<-- remove
  {"user_id": 40, "group": "C"},
  {"user_id": 39, "group": "C"}
]

for(var i = 0; arr.length > i;) {
  if (!arr[i+1] || arr[i].group != arr[i+1].group) {
    arr.splice(i, 1);
  } else if (arr[i].user_id == arr[i+1].user_id || (arr[i-1] && arr[i].user_id == arr[i-1].user_id && arr[i].group == arr[i-1].group)) {
    arr.splice(i, 1);
  } else {
    i += 2;
  }
}

arr.forEach(function(e) {
  document.body.innerHTML += JSON.stringify(e) + "<br>";
});
Johan Karlsson
  • 6,419
  • 1
  • 19
  • 28
1

Here is a solution based on filter and reduce:

var input = [{"user_id": 35, "group": "A"},
             {"user_id": 40, "group": "B"},
             {"user_id": 39, "group": "B"},
             {"user_id": 39, "group": "B"},
             {"user_id": 39, "group": "B"},
             {"user_id": 40, "group": "B"},
             {"user_id": 39, "group": "B"},
             {"user_id": 39, "group": "B"},
             {"user_id": 40, "group": "C"},
             {"user_id": 39, "group": "C"}];

var output = input.filter(function(el, idx, input) {
  // filter unique records
  next = input[idx+1];
  return !next || el.group !== next.group || el.user_id !== next.user_id;
}).reduce(function(prev, el, idx, input) {
  // match pairs if in same group
  next = input[idx+1];
  return (prev.length%2 || next && el.group === next.group)
         ? prev.concat([el]) : prev;
}, []);

// output
document.body.innerHTML = JSON.stringify(output).replace(/\},/g, '}<br>');
trincot
  • 317,000
  • 35
  • 244
  • 286
0

You could use the approach given at How to get unique values in an array to get only the distinct values in the array, then just remove the values that don't have any pairs

[
  {"user_id": 35, "group": "A"}, <-- remove
  {"user_id": 40, "group": "B"},
  {"user_id": 39, "group": "B"},
  {"user_id": 40, "group": "C"},
  {"user_id": 39, "group": "C"}
]
Community
  • 1
  • 1
austin wernli
  • 1,801
  • 12
  • 15