CiscoKidx
CiscoKidx

Reputation: 920

get one of each item from array javascript

I have an array with objects. One of the objects properties is "position". Another is "player_name". There are many players and only 8 unique positions. I want to go through the array and grab the first player for each position and move it to a new array. In the end, I should have a new array with a total of 8 players, each with a unique position.

Here's my code:

// Sample Object: { "name": "Frank Johnson", "position": "C", "cnx": "17" }

function compare(a,b) {
  if (parseFloat(a.cnx) < b.cnx)
    return -1;
  if (parseFloat(a.cnx) > b.cnx)
    return 1;
  return 0;
}

var sorted = array.sort(compare);
var new_array = []
sorted.forEach(function (i) {
  if (i.position === "1B" ) {
    new_array.push(i)
    // How do I make it stop looking for 1B's at this point??
  }
})

Upvotes: 0

Views: 242

Answers (2)

Guffa
Guffa

Reputation: 700212

Keep a map of the positions that you have encountered in the array, and add each object that's not in the map:

function compare(a,b) {
  if (parseFloat(a.cnx) < b.cnx)
    return -1;
  if (parseFloat(a.cnx) > b.cnx)
    return 1;
  return 0;
}

array.sort(compare);
var new_array = [];
var positions = {};
array.forEach(function (i) {
  if (!(i.position in positions)) {
    positions[i.position] = 1;
    new_array.push(i);
  }
});

To get multiple players from any position, you can use the map items as counters and put initial values for specific positions:

array.sort(compare);
var new_array = [];
var positions = { OF: 3 };
array.forEach(function (i) {
  if (!(i.position in positions)) {
    positions[i.position] = 1;
  }
  if (positions[i.position] > 0) {
    positions[i.position]--;
    new_array.push(i);
  }
});

(You can also use that to omit a position, for example { OF: 3, C: 0 }).

Upvotes: 1

Yuri Zarubin
Yuri Zarubin

Reputation: 11677

Using the very popular lodash library:

Assuming you have an array of objects such as:

var data = [
  { "name": "Player 1", "position": "C", "cnx": "17" },
  { "name": "Player 2", "position": "B", "cnx": "17" },
  { "name": "Player 3", "position": "B", "cnx": "17" }
];

You can get the first player by position with:

_.mapValues(_.groupBy(data, 'position'), _.first);

Output:

{
  "C": {
    "name": "Player 1",
    "position": "C",
    "cnx": "17"
  },
  "B": {
    "name": "Player 2",
    "position": "B",
    "cnx": "17"
  }
}

If you want it in array format, you can use:

_.values(_.mapValues(_.groupBy(x, 'position'), _.first))

Output:

[
  {
    "name": "Player 1",
    "position": "C",
    "cnx": "17"
  },
  {
    "name": "Player 2",
    "position": "B",
    "cnx": "17"
  }
]

Upvotes: 0

Related Questions