Home > Blockchain >  How can I get the duplicate objects from this JSON array with JS?
How can I get the duplicate objects from this JSON array with JS?

Time:05-18

From the below JSON I wanted to get the players and list them by how many times they are referenced. So for example Player 3, Chelsea being referenced once, is the top player at #1, then Jim being referenced twice would be #2, then then Player one, Joe, would be the last one of the list because they are referenced 3 times. So from least referenced to most.

I was thinking of doing it with the array filter method via JS but wasn't sure if that would work? Is there a way for me to compare one object in the array to another using filter?

I was thinking something like this JS below, the first part of the for loop, would compare each player to the next in the array, but it wouldn't accurately compare them because it filters for every loop so that I image would destroy performance and be inaccurate filtering. Which is why I also included the if conditional I didn't know if that would be better than filter for this?

let topPlayers = []
for(let i=0; i<players.length; i  ) {
    players.filter((player) => player[i] == player[i   1])

    if(players[i].title == players[i 1].title) {
        topPlayers.push(players[i])
    }
}
const players = [
 {
    "header": "Player",
    "title": "Player one",
    "subtitles": [
      {
        "name": "Joe"
      }
    ],
    "time": "2016-11-08T16:03:08.957Z",
    "products": [
      "Xbox"
    ]
  },
  {
    "header": "Player",
    "title": "Player two",
    "subtitles": [
      {
        "name": "Jim"
      }
    ],
    "time": "2016-11-08T16:03:08.957Z",
    "products": [
      "Xbox"
    ]
  },
  {
    "header": "Player",
    "title": "Player one",
    "subtitles": [
      {
        "name": "Joe"
      }
    ],
    "time": "2016-11-08T16:03:08.957Z",
    "products": [
      "Xbox"
    ]
  },
  {
    "header": "Player",
    "title": "Player two",
    "subtitles": [
      {
        "name": "Jim"
      }
    ],
    "time": "2016-11-08T16:03:08.957Z",
    "products": [
      "Xbox"
    ]
  },
  {
    "header": "Player",
    "title": "Player three",
    "subtitles": [
      {
        "name": "Chelsea"
      }
    ],
    "time": "2016-11-08T16:03:08.957Z",
    "products": [
      "PC"
    ]
  },
  {
    "header": "Player",
    "title": "Player one",
    "subtitles": [
      {
        "name": "Joe"
      }
    ],
    "time": "2016-11-08T16:03:08.957Z",
    "products": [
      "Xbox"
    ]
  }
]

CodePudding user response:

One way of doing it is with a combination of .reduce(..) and .sort(..).

Here is an example:

const players = [
 {
    "header": "Player",
    "title": "Player one",
    "subtitles": [
      {
        "name": "Joe"
      }
    ],
    "time": "2016-11-08T16:03:08.957Z",
    "products": [
      "Xbox"
    ]
  },
  {
    "header": "Player",
    "title": "Player two",
    "subtitles": [
      {
        "name": "Jim"
      }
    ],
    "time": "2016-11-08T16:03:08.957Z",
    "products": [
      "Xbox"
    ]
  },
  {
    "header": "Player",
    "title": "Player one",
    "subtitles": [
      {
        "name": "Joe"
      }
    ],
    "time": "2016-11-08T16:03:08.957Z",
    "products": [
      "Xbox"
    ]
  },
  {
    "header": "Player",
    "title": "Player two",
    "subtitles": [
      {
        "name": "Jim"
      }
    ],
    "time": "2016-11-08T16:03:08.957Z",
    "products": [
      "Xbox"
    ]
  },
  {
    "header": "Player",
    "title": "Player three",
    "subtitles": [
      {
        "name": "Chelsea"
      }
    ],
    "time": "2016-11-08T16:03:08.957Z",
    "products": [
      "PC"
    ]
  },
  {
    "header": "Player",
    "title": "Player one",
    "subtitles": [
      {
        "name": "Joe"
      }
    ],
    "time": "2016-11-08T16:03:08.957Z",
    "products": [
      "Xbox"
    ]
  }
]

const result = players.reduce((a, c) => {
  const found = a.find((o) => o.title === c.title);
  if (found) {
    found.count  ;
    return a;
  }
  a.push({ title: c.title, subtitles: c.subtitles, count: 1 });
  return a;
}, []).sort((a, b) => a.count - b.count);

console.log(result.map((o, i) => `Player: ${o.subtitles[0].name} is #${i 1}`));

What this does is to first reduce the array to an array that only contains unique entries (a simplified version of the original objects) and the number of occurrences of each of this objects (the count property). Then, it sorts the array based on this number.

CodePudding user response:

You could use a another object that will hold one property for each unique player title, then increment value of this property each time the same title is encountered:

const counter = {};

for(const player in players) {

  // checks whether property named as player already exists
  if(!counter[player.title]) {

     // Create new property, named as player, with 1 as value
     counter[player.title] = 1;

  } else {

     // Increment property value
     counter[player.title]  ;
  }

}

for(const player in counter) {
  console.log(`The player ${player} is recorded  ${counter[counter]} times`);
}
  • Related