How can I create a function that will return the number of each breed?
const dogs = [
{
name:"Cherry",
breed:["Shiba", "Poodle"]
},
{
name:"Bolt",
breed:["Shiba"]
},
{
name:"Pumpkin",
breed:["Chihuahua", "Poodle"]
},
{
name:"Happy",
breed:["Poodle"]
},
{
name:"Tofu",
breed:["German Shepherd"]
}
];
I want to print each breeds and its count like below.
{
German Shepherd: 1,
Shiba: 2,
Poodle: 3,
Chihuahua:1
}
Edit: Also how can I pass a specific breed as an argument and print only that breed and its count?
I started understanding some concepts and functions but it is still challenging for me to combine multiple different concepts.
CodePudding user response:
You can use reduce and repeat that on the nested arrays:
const dogs = [{name:"Cherry",breed:["Shiba", "Poodle"]},{name:"Bolt",breed:["Shiba"]},{name:"Pumpkin",breed:["Chihuahua", "Poodle"]},{name:"Happy",breed:["Poodle"]}, {name:"Tofu",breed:["German Shepherd"]}];
const result = dogs.reduce((acc, {breed}) =>
breed.reduce((acc, name) => {
acc[name] = (acc[name] ?? 0) 1;
return acc;
}, acc)
, {});
console.log(result);
Alternatively, you could first flatten the data into an array of strings, and then reduce that:
const dogs = [{name:"Cherry",breed:["Shiba", "Poodle"]},{name:"Bolt",breed:["Shiba"]},{name:"Pumpkin",breed:["Chihuahua", "Poodle"]},{name:"Happy",breed:["Poodle"]}, {name:"Tofu",breed:["German Shepherd"]}];
const result = dogs.flatMap(({breed}) => breed).reduce((acc, name) => {
acc[name] = (acc[name] ?? 0) 1;
return acc;
}, {});
console.log(result);
CodePudding user response:
There's no real need for reduce, filter, or map here.
- Create an object to group the scores by breed.
- Iterate over the
dogsarray, then iterate over the breeds array for each dog. If the breed doesn't already exist on the object create it and set the value to zero. - Add one to the breed value.
In answer to your comment about passing in a separate breed argument to just get the totals for that breed, just amend the function a little.
const dogs=[{name:"Cherry",breed:["Shiba","Poodle"]},{name:"Bolt",breed:["Shiba"]},{name:"Pumpkin",breed:["Chihuahua","Poodle"]},{name:"Happy",breed:["Poodle"]},{name:"Tofu",breed:["German Shepherd"]}];
// Pass in the dogs array
// and an optional query string
function getBreedCount(dogs, query) {
// Grouping object
const obj = {};
// Iterate over the dogs, and the breeds
// updating the grouping object as we go
for (const dog of dogs) {
for (breed of dog.breed) {
obj[breed] ??= 0;
obj[breed];
}
}
// If there is a query argument...
if (query) {
// ...and the query string is a key on the object
// Return a string: `<breed>: <value>`...
if (obj[query]) return `${query}: ${obj[query]}`;
// ...otherwise return a message that
// the breed doesn't exist
return `${query} doesn't exist`;
}
// If there is no query argument
// return the complete object
return obj;
}
console.log(getBreedCount(dogs));
console.log(getBreedCount(dogs, 'Poodle'));
console.log(getBreedCount(dogs, 'Shiba'));
console.log(getBreedCount(dogs, 'Bobby Davro'));
Additional documentation
CodePudding user response:
You can do this. First, Extract the key you want with map (breed).
function getBreed (dog) {
return dog.breed;
}
console.log(dogs.map(getBreed))
// [Array(2), Array(1), Array(2), Array(1), Array(1)]
You can also simplify this with the arrow function
const breeds = dogs.map(dog => dog.breed)
console.log(breeds)
// The same output
// [Array(2), Array(1), Array(2), Array(1), Array(1)]
Then you can merge all arrays into a one-dimensional array with reduce and concat.
const flatten = breeds.reduce((arr, breed) => arr.concat(breed), [])
console.log(flatten)
// ['Shiba', 'Poodle', 'Shiba', 'Chihuahua', 'Poodle', 'Poodle', 'German Shepherd']
Finally, You can count items with reduce
function count(counter, breed) {
if (breed in counter)
counter[breed] ;
else
counter[breed] = 1;
return counter
}
console.log(flatten.reduce(count, {}))
// {Shiba: 2, Poodle: 3, Chihuahua: 1, German Shepherd: 1}
If you wondering what happened here you can see the documentation but in short, The counter is an empty object {} in the first. Then in step 1 it becomes to {Shiba:1} because Sheba wasn't in the counter. In step 2 it becomes {Shiba:1,Poodle:1} for the same reason. In step 3 Sheba Increases and counter becomes {Shiba:2,Poodle:1} because Sheba exists in counter before and etc.
