0

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??
  }
})
6
  • I don't understand the desired behavior. Commented Aug 8, 2015 at 0:42
  • Your code only looks for position "1B". When it stops looking for that, what should it do instead? Commented Aug 8, 2015 at 0:47
  • There are over 300 players in the array. There are 8 unique positions. I am sorting the array by the "cnx. and then want to grab the top 8 players at each position. Because when I sort them a lot of players will have the same position. I dont understand how i should approach this issue. Commented Aug 8, 2015 at 0:48
  • @sails4life can you please create valid example? And if possible a JSFiddle? Where is the array created for you to sort? Commented Aug 8, 2015 at 0:50
  • Yes i am reworking and will post it soon Commented Aug 8, 2015 at 0:51

2 Answers 2

1

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

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

2 Comments

Very elegant. What if I need 3 of just one of the positions? For example, I need 3 "OF" only. One of each of the others.
@sails4life: I added an example for that above.
0

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"
  }
]

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.