How to map an array of object with nested objects and join the values together in the final result

Viewed 67

In Javascript, I'm trying to map an array of objects which has nested objects and the final result should be a new object with a key and the values joined together

For example, below the snippets

const res = [{
  criteria: {
    min: "25",
    max: "100"
  }
}, {
  criteria: {
    min: 0,
    max: "85"
  },
}, {
  criteria: {
    min: "10",
    max: "85"
  },
}, ].map(
  (e) => ({
    valid: e.criteria
  })
)

console.log(res)

That map resulting in this way

[
  {
    "valid": {
      "min": "25",
      "max": "100"
    }
  },
  {
    "valid": {
      "min": 0,
      "max": "85"
    }
  },
  {
    "valid": {
      "min": "10",
      "max": "85"
    }
  }
]

My goal is the following result

[
  {
    "valid": ["25 - 100"]
  },
  {
    "valid": ["0 - 85"]
  },
  {
    "valid": ["10 - 85"]
  }
]

I don't know how to make it happen and also criteria can come like criteria: null The cases are as above we can have both min and max in one obj or have one object with only min or max and one obj with just null.

What could be the best way to achieve my goal that I don't know

UPDATE Some of the information changed as the data coming into this stage was modified to one clear.

The issue with previous coming data is that when min or max was 0 was removed and that causes issue further in the system.

As that has been correct by a colleague the cases are as follow

  1. criteria: min: 0 max: "10" it is valid and will result as ["0 - 10"]
  2. criteria: min: 1000 max: 0 will give an error so no present in data

What will be never in data min or max as alone values

4 Answers

You could achieve this in several steps:

  • get criteria, default to an empty object {}
  • get max, min in criteria, exclude the falsy values (i.e. null, false, empty string)
  • join the range by -
  • exclude falsy values
  • map and get the final result

const res = [
  { criteria: { min: "25", max: "100" } },
  { criteria: { max: "85" } },
  { criteria: { min: "10" } },
  { criteria: { max: "100", min: "" } },
  { criteria: { max: "", min: "" } },
  { criteria: null },
]
  .map(({ criteria }) => criteria || {})
  .map(({ min, max }) => [min, max].filter(Boolean))
  .map(arrOfMinMax => arrOfMinMax.join(" - "))
  .filter(Boolean)
  .map(valid => ({ valid: [valid] }))

console.log(res)

You could concat with a nullish coalescing operator ??.

const
    data = [{ criteria: { min: "25", max: "100" } }, { criteria: { max: "85" } }, { criteria: { min: "10" } }, { criteria: {} }],
    result = data.map(({ criteria: { min, max } = {} }) => ({ valid: []
        .concat(min ?? [], max ?? [])
        .join(' - ') || null
    }));

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

Well you are half way there

const res = [{
  criteria: {
    min: "25",
    max: "100"
  }
}, {
  criteria: {
    max: "85"
  }
  },
  {
  criteria: {
    min: "10"
  }
  }, {criteria: null}, {}
].map(obj => {
if (!obj || !obj.criteria) {
  return {valid: null}
} 

const {min, max} = obj.criteria
if (min && max) {
   return {valid: [`${min} - ${max}`]}
} 
return {valid: [min || max]}
 })


console.log(res)

More convenient way , would be using a traditional for loop, instead of map; you can try the below sample.

const res = [
   {
        criteria: {
            min: "25",
            max: "100"
        }
   }, 
   {
        criteria: {
            max: "85"
       },
   },
   {
       criteria: {
           min: "10"
       },
   }, 
       {
       criteria: null
   }, 

]

let arr = new Array();

for(let i = 0; i< res.length; i++ ){
   if (res[i].criteria === null) continue;
   let min = res[i].criteria.min, max = res[i].criteria.max;
   const str = min && max ? `${min} - ${max}` : min ? min : max ? max : ''
   const objWithMaxMin = {
       valid: [str]
   }
   arr.push(objWithMaxMin)
}

console.log(arr)
Related