2

I have this array of objects, that initially only had name and unit fields. I recently added a unitConv field of array type.

I used to output an array of strings with the name and unit from every object.

const ingredients = [
  {name: 'wine', unit: 'ml', unitConv: []},
  {name: 'salt', unit: 'gr', unitConv: [{unitMeasure: { name: 'spoon'}}, {unitMeasure: { name: 'tea-spoon'}}]},
  {name: 'onion', unit: 'piece', unitConv: []},
]

const response = ingredients.map(ing => `${ing.name} [${ing.unit}]`)

And this is the response:

["wine [ml]", "salt [gr]", "onion [piece]"]

Now that I added unitConv, I want to see if any unitConv are available in the object, and pass those too, as options, like this:

["wine [ml]", "salt [gr]", "onion [piece]", "salt[spoon]", "salt[tea-spoon]"]

And I want to keep the initial value of salt too, the one the uses the 'gr' as a unit. So for salt, because I have one unit and two unitConv, I want to output it three times, with each of this options. If one of the objects doesn't have unitConv, the unitConv fields will appear as an empty array, like in the example above.

2
  • Does my answer work for you? Commented Nov 30, 2020 at 1:09
  • 1
    Yes it does, thank you! Commented Dec 1, 2020 at 9:01

3 Answers 3

5

You can use Array#flatMap to create the second array to concatenate with the first.

const ingredients = [
  {name: 'wine', unit: 'ml', unitConv: []},
  {name: 'salt', unit: 'gr', unitConv: [{unitMeasure: { name: 'spoon'}}, {unitMeasure: { name: 'tea-spoon'}}]},
  {name: 'onion', unit: 'piece', unitConv: []},
]

const response = ingredients.map(ing => `${ing.name} [${ing.unit}]`)
     .concat(ingredients.flatMap(({name, unitConv})=>
         unitConv.map(x => `${name} [${x.unitMeasure.name}]`)));
console.log(response);

Sign up to request clarification or add additional context in comments.

Comments

0

a simple array reduce method:

const ingredients = 
        [ { name: 'wine', unit: 'ml', unitConv: [] } 
        , { name: 'salt', unit: 'gr', unitConv: 
              [ { unitMeasure: { name: 'spoon'     } } 
              , { unitMeasure: { name: 'tea-spoon' } } 
              ] 
          } 
        , { name: 'onion', unit: 'piece', unitConv: [] } 
        ] 

const resp2 = ingredients.reduce((resp,{name,unit,unitConv}) =>
        {
        resp.push( `${name} [${unit}]` )
        unitConv.forEach(({unitMeasure}) =>
          resp.push(`${name} [${unitMeasure.name}]`))
        return resp
        },[])

console.log( resp2 )
.as-console-wrapper{max-height:100% !important;top: 0;}

Comments

0

you can use flatMap and inside its callback function check for unitConv array lentgh, if it's true then you can use a map for that. here is the demo:

const ingredients = [{
    name: 'wine',
    unit: 'ml',
    unitConv: []
  },
  {
    name: 'salt',
    unit: 'gr',
    unitConv: [{
      unitMeasure: {
        name: 'spoon'
      }
    }, {
      unitMeasure: {
        name: 'tea-spoon'
      }
    }]
  },
  {
    name: 'onion',
    unit: 'piece',
    unitConv: []
  },
]

function strFormat(name, unit) {
  return `${name} [${unit}]`;
}

const result = ingredients.flatMap((ing) => {
  if (ing.unitConv.length) {
    const ingAllUnits = ing.unitConv.map((unit) => strFormat(ing.name, unit.unitMeasure.name));
    ingAllUnits.push(strFormat(ing.name, ing.unit));
    return ingAllUnits;
  } else return strFormat(ing.name, ing.unit);
});

console.log(result);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.