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:
teamsAndOwnedCards
which looks like{"Indianapolis Colts":1,"Miami Dolphins":1,"Washington Redskins":44}
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!