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
dogs
array, 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.