0

I have an array as shown below

 [
  {
    "id": 42,
    "name": "updateDate",
    "displayName": "UPDATE DATE",
    "uiControl": "DATERANGE",
    "dataType": "STRING",
    "uiOrder": 1,

  },
  {
    "id": 44,
    "name": "name",
    "displayName": "First Name",
    "uiControl": "TEXTBOX",
    "dataType": "STRING",
    "uiOrder": 1,
  },
]

I want to filter objects in this array with the property UiControl === DATERANGE and create 2 objects from the filtered object and also append'FROM' and 'TO' to the name and the displayname property as shown below

final output:

[{
  "id": 42,
  "name": "fromupdateDate",            // 'from'appended to name property
  "displayName": "FROM UPDATE DATE",   // 'FROM' appended to displayName property
  "uiControl": "DATERANGE",
  "dataType": "STRING",
  "uiOrder": 1,
 },
 {
  "id": 42,
  "name": "toupdateDate",               // 'to' appended to name property
  "displayName": "TO UPDATE DATE",      // 'TO' appended to displayName
  "uiControl": "DATERANGE",
  "dataType": "STRING",
  "uiOrder": 1,
 },
 {                                      // this object stays the same
   "id": 44,
   "name": "name",
   "displayName": "First Name",
   "uiControl": "TEXTBOX",
   "dataType": "STRING",
   "uiOrder": 1,
  }]


We can create such an array in multiple ways, but I want to find an optimized way of creating such an object. 
prabhat gundepalli
  • 907
  • 3
  • 15
  • 39

1 Answers1

1

flatMap will do what you want:

const input = [{
    "id": 42,
    "name": "updateDate",
    "displayName": "UPDATE DATE",
    "uiControl": "DATERANGE",
    "dataType": "STRING",
    "uiOrder": 1,

  },
  {
    "id": 44,
    "name": "name",
    "displayName": "First Name",
    "uiControl": "TEXTBOX",
    "dataType": "STRING",
    "uiOrder": 1,
  },
];
const output = input.flatMap(v => v.uiControl === "DATERANGE" 
  ? [
      { ...v,
        name: `from${v.name}`,
        displayName: `FROM ${v.displayName}`
      },
      { ...v,
        name: `to${v.name}`,
        displayName: `TO ${v.displayName}`
      }
    ] 
  : [v]);
console.log(output);

Note that you'll have to compile this with esnext support. See this question for more details. It also won't work out of the box on IE or Edge. If that's a problem in your use case, you'll want to use a polyfill or rely on map + reduce like this:

const output = input.map(v => v.uiControl === "DATERANGE" 
  ? [
      { ...v,
        name: `from${v.name}`,
        displayName: `FROM ${v.displayName}`
      },
      { ...v,
        name: `to${v.name}`,
        displayName: `TO ${v.displayName}`
      }
    ] 
  : [v])
  .reduce((acc, cur) => (acc.push(...cur), acc), []);
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331