Map array in descending order of the sum of the elements of an array

Viewed 37

I have a JSON that looks like this:

{
"user": [
   {"username": "x1", "pfp": "", "scores": [{"easy": 10, "normal": 1, "hard": 2, "oni": 3, "uraoni": 4}]},
   {"username": "x2", "pfp": "", "scores": [{"easy": 3, "normal": 1, "hard": 2, "oni": 3, "uraoni": 4}]},
   {"username": "x3", "pfp": "", "scores": [{"easy": 5, "normal": 1, "hard": 2, "oni": 3, "uraoni": 4}]},
   {"username": "x4", "pfp": "", "scores": [{"easy": 0, "normal": 40, "hard": 2, "oni": 3, "uraoni": 4}]}
]
}

Expected output of the order by username: x4, x1, x3, x2 (x4 would have a value of 49, x1 a value of 20, x2 a value of 15 and x3 a value of 13).

and I need to map() the array in the order of the sum of the scores array.

I tried doing a map for reduce() the scores and then sort() it but it didn't let me reduce() it.

let userscopy = userjson
  userscopy.map((user) => (
    user.scores[0] = JSON.parse(user.scores).reduce((a, b) => a + b)
  ))

The error in question Any ideas?

3 Answers

Is this what you need by chance?

const userjson = {
  "user": [{
      "username": "x",
      "pfp": "",
      "scores": [{
        "easy": 0,
        "normal": 1,
        "hard": 2,
        "oni": 3,
        "uraoni": 4
      }]
    },
    {
      "username": "x",
      "pfp": "",
      "scores": [{
        "easy": 0,
        "normal": 1,
        "hard": 2,
        "oni": 3,
        "uraoni": 4
      }]
    },
    {
      "username": "x",
      "pfp": "",
      "scores": [{
        "easy": 0,
        "normal": 1,
        "hard": 2,
        "oni": 3,
        "uraoni": 4
      }]
    },
    {
      "username": "x",
      "pfp": "",
      "scores": [{
        "easy": 0,
        "normal": 1,
        "hard": 2,
        "oni": 3,
        "uraoni": 4
  }]
}

] }

1- .map() only works with arrays so instead of userjson.map() use userjson.user.map() since the array is inside the user property

2- Remove the JSON.parse() since is not a valid json at the moment

3- use index for your x.scores[i]

const result = userjson.user.map((x,i) => (
    x.scores[i] = x.scores.reduce((a, b) => a + b)
  ))
  
console.log(result);

You could define an helper function total and sort by it:

const data = {
  user: [
    {
      username: 'x1',
      pfp: '',
      scores: [{ easy: 10, normal: 1, hard: 2, oni: 3, uraoni: 4 }],
    },
    {
      username: 'x2',
      pfp: '',
      scores: [{ easy: 3, normal: 1, hard: 2, oni: 3, uraoni: 4 }],
    },
    {
      username: 'x3',
      pfp: '',
      scores: [{ easy: 5, normal: 1, hard: 2, oni: 3, uraoni: 4 }],
    },
    {
      username: 'x4',
      pfp: '',
      scores: [{ easy: 0, normal: 40, hard: 2, oni: 3, uraoni: 4 }],
    },
  ],
};

const total = (user) => {
  if (user.scores.length === 0) return 0;
  const { easy, normal, hard, oni, uraoni } = user.scores[0];
  return easy + normal + hard + oni + uraoni;
};

const res = data.user.sort((a, b) => total(b) - total(a));

console.log(res);

const data = {
"user": [
   {"username": "x1", "pfp": "", "scores": [{"easy": 10, "normal": 1, "hard": 2, "oni": 3, "uraoni": 4}]},
   {"username": "x2", "pfp": "", "scores": [{"easy": 3, "normal": 1, "hard": 2, "oni": 3, "uraoni": 4}]},
   {"username": "x3", "pfp": "", "scores": [{"easy": 5, "normal": 1, "hard": 2, "oni": 3, "uraoni": 4}]},
   {"username": "x4", "pfp": "", "scores": [{"easy": 0, "normal": 40, "hard": 2, "oni": 3, "uraoni": 4}]}
]
};

const order = data.user
  .sort((a, b) => addScores(b.scores[0]) - addScores(a.scores[0]))
  .map(({ username }) => username);

console.log(order);

function addScores(scores) {
  return Object.values(scores).reduce((p, n) => p + n, 0);
}

Related