const recipes = [
{
title: 'Crepes',
duration: 60,
ingredients: ['butter', 'flour', 'eggs', 'milk', 'salt'],
servings: 3
},
{
title: 'Scrambled Eggs',
duration: 20,
ingredients: ['eggs', 'milk', 'salt'],
servings: 2
},
{
title: 'Vegan Salmon',
duration: 60 * 24 * 3, // 3 days
ingredients: ['carrots', 'olive oil', 'nori sheets', 'liquid smoke', 'soy sauce'],
servings: 10
},
{
title: 'Carot Cake',
duration: 120,
ingredients: ['carrots', 'flour', 'eggs', 'salt', 'milk', 'sugar'],
servings: 10
}
]
I want to create an array like this:
['Crepes (60min)', ...]
Thats my code so far:
const titlesWithDuration = recipes.map((titles) => {
return `${titles.title} (${titles.duration}min)`;
});
console.log(titlesWithDuration)
Problem is, if i use things like operators, for example:
titles.duration <= 60
i will get this:
["Crepes (truemin)","Scrambled Eggs (truemin)","Vegan Salmon (falsemin)","Carot Cake (falsemin)"]
How can i use operators which give me a string output?
CodePudding user response:
map
does a one-for-one mapping, but in your example, you want to leave out some elements. That's a filtering operation.
For the vast majority of use cases, you can just filter
and then map
:
const titlesWithDuration = recipes
.filter(({duration}) => duration <= 60)
.map(({title, duration}) => `${title} (${duration}min)`);
Live Example:
const recipes = [
{
title: 'Crepes',
duration: 60,
ingredients: ['butter', 'flour', 'eggs', 'milk', 'salt'],
servings: 3
},
{
title: 'Scrambled Eggs',
duration: 20,
ingredients: ['eggs', 'milk', 'salt'],
servings: 2
},
{
title: 'Vegan Salmon',
duration: 60 * 24 * 3, // 3 days
ingredients: ['carrots', 'olive oil', 'nori sheets', 'liquid smoke', 'soy sauce'],
servings: 10
},
{
title: 'Carot Cake',
duration: 120,
ingredients: ['carrots', 'flour', 'eggs', 'salt', 'milk', 'sugar'],
servings: 10
}
];
const titlesWithDuration = recipes
.filter(({duration}) => duration <= 60)
.map(({title, duration}) => `${title} (${duration}min)`);
console.log(titlesWithDuration);
In the rare situation where you want to avoid multiple trips through the array, you could use a generator function version of filter
and Array.from
(using its mapping callback argument) to build the result:
function* filter(it, callback) {
for (const element of it) {
if (callback(element)) {
yield element;
}
}
}
const titlesWithDuration = Array.from(
filter(recipes, ({duration}) => duration <= 60),
({title, duration}) => `${title} (${duration}min)`
);
Live Example:
const recipes = [
{
title: 'Crepes',
duration: 60,
ingredients: ['butter', 'flour', 'eggs', 'milk', 'salt'],
servings: 3
},
{
title: 'Scrambled Eggs',
duration: 20,
ingredients: ['eggs', 'milk', 'salt'],
servings: 2
},
{
title: 'Vegan Salmon',
duration: 60 * 24 * 3, // 3 days
ingredients: ['carrots', 'olive oil', 'nori sheets', 'liquid smoke', 'soy sauce'],
servings: 10
},
{
title: 'Carot Cake',
duration: 120,
ingredients: ['carrots', 'flour', 'eggs', 'salt', 'milk', 'sugar'],
servings: 10
}
];
function* filter(it, callback) {
for (const element of it) {
if (callback(element)) {
yield element;
}
}
}
const titlesWithDuration = Array.from(
filter(recipes, ({duration}) => duration <= 60),
({title, duration}) => `${title} (${duration}min)`
);
console.log(titlesWithDuration);
CodePudding user response:
Array's map and filter methods will help to do the expected result. map will do the transition and filter will help to apply condition.
result = recipes.filter(ele=>ele.duration <=60).map(ele=> `${ele.title} (${ele.duration}min)`);
result would be
['Crepes (60min)', 'Scrambled Eggs (20min)']