Search code examples
javascriptarraysobjectoperatorsoperator-keyword

How can i pick out the integers that are smaller or equal to 60 with .map array method


 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?


Solution

  • 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);