1

I know how to loop through an object and print out an array of values I want, but I'm having trouble figuring out printing it in the order that I want .

**The question is: **

Given a collection of game outcome records, determine who all the players are by returning an array of their names.

The array should be ordered by how the names are encountered.

Example Input:

[
  { winner: 'Alishah', loser: 'Bob',    loser_points: 3 },
  { winner: 'Maria',   loser: 'Xu Jin', loser_points: 1 },
  { winner: 'Elise',   loser: 'Bob',    loser_points: 2 },
  { winner: 'Elise',   loser: 'Maria',  loser_points: 4 },
  { winner: 'Alishah', loser: 'Maria',  loser_points: 2 },
  { winner: 'Maria',   loser: 'Xu Jin', loser_points: 3 },
  { winner: 'Xu Jin',  loser: 'Elise',  loser_points: 2 }
]

Expected Result:

['Alishah', 'Bob', 'Maria', 'Xu Jin', 'Elise']

**The code I have so far: **

let data = [
  { winner: 'Alishah', loser: 'Bob',    loser_points: 3 },
  { winner: 'Maria',   loser: 'Xu Jin', loser_points: 1 },
  { winner: 'Elise',   loser: 'Bob',    loser_points: 2 },
  { winner: 'Elise',   loser: 'Maria',  loser_points: 4 },
  { winner: 'Alishah', loser: 'Maria',  loser_points: 2 },
  { winner: 'Maria',   loser: 'Xu Jin', loser_points: 3 },
  { winner: 'Xu Jin',  loser: 'Elise',  loser_points: 2 }
];

   
console.log(main(data));

7 Answers 7

4

You can use .flatMap() and Set() for this:

let data = [
  { winner: 'Alishah', loser: 'Bob',    loser_points: 3 },
  { winner: 'Maria',   loser: 'Xu Jin', loser_points: 1 },
  { winner: 'Elise',   loser: 'Bob',    loser_points: 2 },
  { winner: 'Elise',   loser: 'Maria',  loser_points: 4 },
  { winner: 'Alishah', loser: 'Maria',  loser_points: 2 },
  { winner: 'Maria',   loser: 'Xu Jin', loser_points: 3 },
  { winner: 'Xu Jin',  loser: 'Elise',  loser_points: 2 }
];

const res = [...new Set(data.flatMap(x=>[x.winner, x.loser]))]
console.log( res )

Explanation:

  • Using .flatMap() method we will first get an array of arrays. Here the inner array will be array of winner & loser names.
  • Then we will flatten the array to get a single array of all player's name.
  • And finally using [...new Set(array)] we will get distinct names in the array to achieve the desired result.
Sign up to request clarification or add additional context in comments.

Comments

3

You can use Array.reduce() and Set to get names and remove duplicates

Array.reduce() iterates over the array. So you can push all winners and losers to the initial empty array.

Then you can create a new Set. This way, you can remove duplicates (since all items are string). After that, you can convert it back to array by using the spread syntax: [...new Set(array)]

const arr = [
  { winner: 'Alishah', loser: 'Bob',    loser_points: 3 },
  { winner: 'Maria',   loser: 'Xu Jin', loser_points: 1 },
  { winner: 'Elise',   loser: 'Bob',    loser_points: 2 },
  { winner: 'Elise',   loser: 'Maria',  loser_points: 4 },
  { winner: 'Alishah', loser: 'Maria',  loser_points: 2 },
  { winner: 'Maria',   loser: 'Xu Jin', loser_points: 3 },
  { winner: 'Xu Jin',  loser: 'Elise',  loser_points: 2 }
]

const names = [...new Set(arr.reduce((acc, cur) => [...acc, cur.winner, cur.loser], []))]

console.log(names)

Comments

0
var players = collection.reduce((acc, player) => {
    if(!acc.inStore[player.winner]) {
        acc.players.push(player.winner)
        acc.inStore[player.winner] = true
    }
    if(!acc.inStore[player.loser]) {
        acc.players.push(player.loser)
        acc.inStore[player.loser] = true
    }
    return acc;
}, {players: [], inStore: {}}).players

// ["Alishah", "Bob", "Maria", "Xu Jin", "Elise"]

Comments

0

Use reduce and includes

console.clear();

"use strict";

const score = [
  { winner: 'Alishah', loser: 'Bob',    loser_points: 3 },
  { winner: 'Maria',   loser: 'Xu Jin', loser_points: 1 },
  { winner: 'Elise',   loser: 'Bob',    loser_points: 2 },
  { winner: 'Elise',   loser: 'Maria',  loser_points: 4 },
  { winner: 'Alishah', loser: 'Maria',  loser_points: 2 },
  { winner: 'Maria',   loser: 'Xu Jin', loser_points: 3 },
  { winner: 'Xu Jin',  loser: 'Elise',  loser_points: 2 }
]

function reduce(coll, {winner, loser}) {
  if (!coll.includes(winner)) {
    coll.push(winner)
  }
  if (!coll.includes(loser)) {
    coll.push(loser)
  }
  return coll;
}

var players = score.reduce(reduce, [])
console.log(players)

1 Comment

This is not matching the expected result OP has shared: ['Alishah', 'Bob', 'Maria', 'Xu Jin', 'Elise']
0

Looking your code and your expected result I think you're missing to push into arr also the looser name. To fix it my favourite approach is the reduce method of js array:

const arr = outcomes.reduce((completeList,{winner, looser}) => {
    const extraNames = [winner, looser]
        .filter(x => !completeList.includes(x));
    return [
        ...completeList,
        ...extraNames
    ];
}, []);

1 Comment

This produces duplicates, each name should only show up once.
0

Using map and filter

let array = [
  { winner: 'Alishah', loser: 'Bob',    loser_points: 3 },
  { winner: 'Maria',   loser: 'Xu Jin', loser_points: 1 },
  { winner: 'Elise',   loser: 'Bob',    loser_points: 2 },
  { winner: 'Elise',   loser: 'Maria',  loser_points: 4 },
  { winner: 'Alishah', loser: 'Maria',  loser_points: 2 },
  { winner: 'Maria',   loser: 'Xu Jin', loser_points: 3 },
  { winner: 'Xu Jin',  loser: 'Elise',  loser_points: 2 }
];

let winners = array.map(i => i.winner).filter((x, i, a) => a.indexOf(x) == i)
console.log(winners);

Comments

-1

const outcomes = [
  { winner: 'Alishah', loser: 'Bob',    loser_points: 3 },
  { winner: 'Maria',   loser: 'Xu Jin', loser_points: 1 },
  { winner: 'Elise',   loser: 'Bob',    loser_points: 2 },
  { winner: 'Elise',   loser: 'Maria',  loser_points: 4 },
  { winner: 'Alishah', loser: 'Maria',  loser_points: 2 },
  { winner: 'Maria',   loser: 'Xu Jin', loser_points: 3 },
  { winner: 'Xu Jin',  loser: 'Elise',  loser_points: 2 }
];

const result = outcomes.reduce((acc, cur) => {
  if(!acc.includes(cur.winner))
  acc.push(cur.winner);
  if(!acc.includes(cur.loser))
  acc.push(cur.loser);
  return acc;
}, []).join(",");

console.log(result);

2 Comments

This is also not matching the expected result OP has shared: ['Alishah', 'Bob', 'Maria', 'Xu Jin', 'Elise']
@palaѕн Good catch.

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.