1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Combine objects with the same values/id and add sum to new object

Discussion in 'JavaScript' started by Helen Tashot, Aug 25, 2020.

  1. #1
    I have an array of objects that looks like this:

    const teams =[{
    name:'Liverpool',
    won:true,
    opponent:'Man Utd'},{
    name:'Liverpool',
    won:true,
    opponent:'Liverpool'},{
    name:'Chelsea',
    won:false,
    opponent:'Arsenal'},{
    name:'Newcastle',
    won:true,
    opponent:'Liverpool'}];
    Code (markup):
    I want the final array to look like the following. It should only add one team to the new array and calculate how many games the team has won. The order doesn't really matter.

    const transformedTeams =[{
    name:'Liverpool',
    won:2},{
    name:'Newcastle',
    won:1},{
    name:'Chelsea',
    won:0}];
    Code (markup):
    The code I have written looks like this, but unfortunately isn't returning the correct value:

    teams.map(team =>{if(teams.includes(team.name)){return{
    name: team.name,
    won: team.won ===true?1:0}}})
    Code (markup):
     
    Last edited by a moderator: Aug 25, 2020
    Helen Tashot, Aug 25, 2020 IP
  2. sarahk

    sarahk iTamer Staff

    Messages:
    28,500
    Likes Received:
    4,460
    Best Answers:
    123
    Trophy Points:
    665
    #2
    Not as tidy as using map but it works
    const teams = [
      { name: "Liverpool", won: true, opponent: "Man Utd" },
      { name: "Liverpool", won: true, opponent: "Liverpool" },
      { name: "Chelsea", won: false, opponent: "Arsenal" },
      { name: "Newcastle", won: true, opponent: "Liverpool" }
    ];
    
    var transformedTeams = [];
    
    teams.forEach(function (team) {
      let found = false;
    
      transformedTeams.forEach(function (tt) {
        if (tt.name === team.name) {
          found = true;
          if (team.won === true) {
            tt.won++;
          }
        }
      });
      if (found === false) {
        transformedTeams.push({ name: team.name, won: team.won ? 1 : 0 });
      }
    });
    Code (JavaScript):
     
    sarahk, Aug 25, 2020 IP
  3. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #3
    Since you only have two properties, wouldn't an Object (or maybe Map?) where the team name is the index and the number of wins is the value be better?

    const teams = [
      { name: "Liverpool", won: true, opponent: "Man Utd" },
      { name: "Liverpool", won: true, opponent: "Liverpool" },
      { name: "Chelsea", won: false, opponent: "Arsenal" },
      { name: "Newcastle", won: true, opponent: "Liverpool" }
    ];
    
    var teamWins = {};
    
    for (var game of teams) {
    	if (game.won) {
    		if (!teamWins[game.name]) teamWins[game.name] = 1;
    		else teamWins[game.name]++;
    	}
    }
    Code (markup):
    ... and @sarahk, foreach is crap because it's "Callback for nothing". I HIGHLY suggest against ever using it due to the excess wasteful overhead. for/of is your friend... as are labels.

    
    gameloop: for (var game of teams) {
    	if (team.won) {
    		for (var info of transformedTeams) {
    			if (info.name === team.name) {
    				if (team.woninfo.won++;
    				continue gameLoop;
    			}
    		}
    		trasnformedTeams.push({ name : game.name, won :1 });
    	}
    }
    
    Code (markup):
    Admittedly, the above filters out teams that never won.
     
    deathshadow, Aug 29, 2020 IP