Home > Software engineering >  Adding New Properties to Object from other Objects
Adding New Properties to Object from other Objects

Time:03-16

I am trying to merge data from two objects into another object which is used to present markers on a Leaflet map.

At a high level I am trying to supplement an object that looks like the below:

const teams = {
    "Washington Redskins": {
        primary: "#000000",
        secondary: "#97233f",
        coordinates: {
            lat: 33.5276,
            lon: -112.263275
        }
    },
    "Indianapolis Colts": {
        primary: "#000000",
        secondary: "#a71930",
        coordinates: {
            lat: 33.755489,
            lon: -84.401993
        }
    },
    "Baltimore Ravens": {
        primary: "#9e7c0c",
        secondary: "#241773",
        coordinates: {
            lat: 39.278088,
            lon: -76.623322
        }
    }
  }

With data from two other objects so that for each team two additional properties are added and the object looks like:

"Indianapolis Colts": {
        primary: "#000000",
        secondary: "#a71930",
        ownedCards: 1 ← a dynamic value based on calculations on another object
        wantedCards: 4 ← a dynamic value based on calculations on another object
        coordinates: {
            lat: 33.755489,
            lon: -84.401993
        }
    },
…. ,

At the bottom of this question is the full code I have so far, but I'll set out below the particular parts I'm struggling with.

Having done work to pull out a list of unique teams in a person's collection, and the number of times that team appears in the collection I am left with with two objects:

  1. teamsAndOwnedCards which looks like {"Indianapolis Colts":1,"Miami Dolphins":1,"Washington Redskins":44}
  2. teamsAndWantedCards which looks like {"Green Bay Packers":3,"Miami Dolphins":1,"Dallas Cowboys:2}

for each team in the teamsAndOwnedCards object I would like to insert a property against the matching team in the teams object, for example

"Indianapolis Colts": {
        primary: "#000000",
        secondary: "#a71930",
        ownedCards: 1 ← a dynamic value based on values in teamsAndOwnedCards
        coordinates: {
            lat: 33.755489,
            lon: -84.401993
        }
    },
…. ,

and the same for teams in the teamsAndWantedCards object, except that here the property added would be wantedCards: 2 (where 2 is the value that team has in the teamsAndWantedCards object, so in this case Dallas Cowboys.

Below if the full code that shows how I am deriving the teams and the number of times they appear in the user's collections. It may not be the best but it gets me the data I need i.e. teamsAndOwnedCards and teamsAndWantedCards, it's how I get this data into the teams object that I'm struggling with,

const ownedCards = [{"_id":{"$oid":"61b27483578427ce31d1571f"},"card_id":"61afd5eb170010f187fa10d0","brand":"Contenders","status":"Own","team":"Washington Redskins","collection_type":"Football"},{"_id":{"$oid":"61b27483578427ce31d15720"},"card_id":"61afd5ef170010f187fa5ad6","brand":"National Treasures","status":"Own","team":"Washington Redskins","collection_type":"Football"},{"_id":{"$oid":"61d850d6b6d67e836eab9871"},"card_id":"61afd4d5170010f187e9c0db","brand":"Black","status":"Own","team":"Indianapolis Colts","collection_type":"Football"},{"_id":{"$oid":"61e995ff2738954edae011ec"},"card_id":"61ddf5b768ebbba1a4fd2c33","brand":"Black","status":"Own","team":"Alabama","collection_type":"Football"}]

const wantedCards = [{"_id":{"$oid":"61b27659578427ce31d1e4f8"},"card_id":"61afd5ef170010f187fa5a46","brand":"National Treasures","status":"Want","team":"Washington Redskins","collection_type":"Football"},{"_id":{"$oid":"61b279fa578427ce31d302d9"},"card_id":"61afd5e2170010f187f98cf5","brand":"National Treasures","status":"Want","team":"Washington Football Team","collection_type":"Football"},{"_id":{"$oid":"61bfa860b6d67e836ef9e2cc"},"card_id":"61afd5e2170010f187f98cf5","brand":"National Treasures","status":"Want","team":"LSU", "collection_type":"Baseball"}]


const teams = {
    "Washington Redskins": {
        primary: "#000000",
        secondary: "#97233f",
        coordinates: {
            lat: 33.5276,
            lon: -112.263275
        }
    },
    "Indianapolis Colts": {
        primary: "#000000",
        secondary: "#a71930",
        coordinates: {
            lat: 33.755489,
            lon: -84.401993
        }
    },
    "Baltimore Ravens": {
        primary: "#9e7c0c",
        secondary: "#241773",
        coordinates: {
            lat: 39.278088,
            lon: -76.623322
        }
    }
   }

  //get an array of teams from the team file
    const listofTeams = Object.keys(teams).map((key) => {
        //const nestedObject = teams[key]
        const nestedObject = key

        return nestedObject
    })
     console.log("listofTeams"   JSON.stringify(listofTeams))

   
//a function to count the number of times a team appears in a collection
const countUnique = arr => {
    const counts = {};
    for (var i = 0; i < arr.length; i  ) {
        counts[arr[i]] = 1   (counts[arr[i]] || 0);
    };
    return counts;
};

// create an array of teams in the collection
  const arrayOfOwnedTeams = ownedCards.map(a => a.team);
  
//get the number of times a team appears in the array
  const countOfOwnedTeams = countUnique(arrayOfOwnedTeams)
    console.log("countOfOwnedTeams"   JSON.stringify(countOfOwnedTeams))

    //get the number of times a team appears int he wanted card colelciton
  const arrayOfWantedTeams = wantedCards.map(a => a.team);
    const countOfWantedTeams = countUnique(arrayOfWantedTeams)
    console.log("countOfWantedTeams"   JSON.stringify(countOfWantedTeams))



  //make sure that only those owned cards that are in the teams list are shown in the list of teams with cards (because e.g. I don't support college teams e.g. LSU)
    const teamsAndOwnedCards = listofTeams.reduce((acc, el) => {
        if (el in countOfOwnedTeams) acc[el] = countOfOwnedTeams[el];
        return acc;
    }, {});

    console.log("teamsAndOwnedCards"   JSON.stringify(teamsAndOwnedCards))
    
    
  //do the same for wanted cards
    const teamsAndWantedCards = listofTeams.reduce((acc, el) => {
        if (el in countOfWantedTeams) acc[el] = countOfWantedTeams[el];
        return acc;
    }, {});

    console.log("teamsAndWantedCards"   JSON.stringify(teamsAndWantedCards))
    
    //convert the owned cards object into an array, so it can be mapped over into a new object
    const arrayOfOwnedTeamsAndCards = Object.entries(teamsAndOwnedCards)
    //create a new object with a structure the same as the teams object 
    const objectFromArrayOfOwnedTeamsAndCards = arrayOfOwnedTeamsAndCards.map(([key, value]) => ({ [key]: { ownedCards: value } }))
    console.log("objectFromArrayOfOwnedTeamsAndCards"   JSON.stringify(objectFromArrayOfOwnedTeamsAndCards))
    
        //convert the wanted cards object into an array, so it can be mapped over into a new object
    const arrayOfWantedTeamsAndCards = Object.entries(teamsAndWantedCards)
    //create a new object with a structure the same as the teams object (BUT, it's an array - aargh!)
    const objectFromArrayOfWantedTeamsAndCards = arrayOfWantedTeamsAndCards.map(([key, value]) => ({ [key]: { ownedCards: value } }))
    console.log("objectFromArrayOfWantedTeamsAndCards"   JSON.stringify(objectFromArrayOfWantedTeamsAndCards))
    

Can anyone advise on a more efficient way to do this please?

CodePudding user response:

You can do this by calling Object.assign on the team data and your given new data. Here's my solution which uses a helper function that takes in a given team name:

const teams = {
    "Washington Redskins": {
        primary: "#000000",
        secondary: "#97233f",
        coordinates: {
            lat: 33.5276,
            lon: -112.263275
        }
    },
    "Indianapolis Colts": {
        primary: "#000000",
        secondary: "#a71930",
        coordinates: {
            lat: 33.755489,
            lon: -84.401993
        }
    },
    "Baltimore Ravens": {
        primary: "#9e7c0c",
        secondary: "#241773",
        coordinates: {
            lat: 39.278088,
            lon: -76.623322
        }
    }
}

function mergeTeamData(name, data) {
    Object.assign(teams[name], data);
}

console.log(teams["Indianapolis Colts"]); // original data

mergeTeamData("Indianapolis Colts", {
    ownedCards: 1,
    wantedCards: 4
})

console.log(teams["Indianapolis Colts"]); // correctly updated!
  • Related