Home > Software design >  How to reduce my object array into a single depth in javascript?
How to reduce my object array into a single depth in javascript?

Time:07-29

Good day, I would like to bind a drop down to values that comes from an object array? I have done the following and not sure how to:

JS Code:

const objArray = [
    {
        "type": "select",
        "required": false,
        "label": "WorkTime",
        "name": "select-1659012135405-0",
        "customFieldId": "4330",
        "fieldCode": "WT1",
        "advancedSettings": "Edit",
        "typeDescription": "Select",
        "values": [
            {
                "label": "Apples",
                "value": "AP",
                "selected": false
            },
            {
                "label": "Bananas",
                "value": "BA",
                "selected": false
            },
            {
                "label": "Pineapples",
                "value": "PI",
                "selected": false
            }
        ]
    },
    {
        "type": "select",
        "required": false,
        "label": "WorkHours",
        "name": "select-1659012135415-0",
        "customFieldId": "13916",
        "fieldCode": "WH",
        "advancedSettings": "Edit",
        "typeDescription": "Select",
        "values": [
            {
                "label": "Day",
                "value": "D",
                "selected": false
            },
            {
                "label": "Night",
                "value": "N",
                "selected": false
            }
        ]
    }
];

const result = objArray.map(({customFieldId, fieldCode, label, values}) => {
  if (!values) { return; }
  
  return values.reduce((obj, key, index) => {
     return Object.assign(obj, {
      [`${customFieldId}-${index}`]: 
      { 
        value: `${customFieldId}-${fieldCode}-${key.value}`,
        text: `${fieldCode} - ${label} - ${key.label}`
      }
     });  
  }, {});
});

console.log(result);

Current Result:

[{
  4330-0: {
    text: "WT1 - WorkTime - Apples",
    value: "4330-WT1-AP"
  },
  4330-1: {
    text: "WT1 - WorkTime - Bananas",
    value: "4330-WT1-BA"
  },
  4330-2: {
    text: "WT1 - WorkTime - Pineapples",
    value: "4330-WT1-PI"
  }
}, {
  13916-0: {
    text: "WH - WorkHours - Day",
    value: "13916-WH-D"
  },
  13916-1: {
    text: "WH - WorkHours - Night",
    value: "13916-WH-N"
  }
}]

Expected Result:

[
  {
    text: "WT1 - WorkTime - Apples",
    value: "4330-WT1-AP"
  },
  {
    text: "WT1 - WorkTime - Bananas",
    value: "4330-WT1-BA"
  },
  {
    text: "WT1 - WorkTime - Pineapples",
    value: "4330-WT1-PI"
  },
  {
    text: "WH - WorkHours - Day",
    value: "13916-WH-D"
  },
  {
    text: "WH - WorkHours - Night",
    value: "13916-WH-N"
  }
]

To bind to the dropdown lookup, the Key will be value and DisplayText will text.How can I achieve this?

CodePudding user response:

You could take flatMap for the outer array and map the new object with the inner arrays.

const
    data = [{ type: "select", required: false, label: "WorkTime", name: "select-1659012135405-0", customFieldId: "4330", fieldCode: "WT1", advancedSettings: "Edit", typeDescription: "Select", values: [{ label: "Apples", value: "AP", selected: false }, { label: "Bananas", value: "BA", selected: false }, { label: "Pineapples", value: "PI", selected: false }] }, { type: "select", required: false, label: "WorkHours", name: "select-1659012135415-0", customFieldId: "13916", fieldCode: "WH", advancedSettings: "Edit", typeDescription: "Select", values: [{ label: "Day", value: "D", selected: false }, { label: "Night", value: "N", selected: false }] }],
    result = data.flatMap(({ fieldCode, label, customFieldId, values }) =>
        values.map(o => ({
            text: [fieldCode, label, o.label].join(' - '),
            value: [customFieldId, fieldCode, o.value].join('-')
        }))
    );

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

CodePudding user response:

const result = objArray.reduce((acc, next) => {
  next.values.forEach(valueObj => {
    acc.push({
      text: `${next.fieldCode} - ${next.label} - ${valueObj.label}`,
      value: `${next.customFieldId}-${next.fieldCode}-${valueObj.value}`
    })
  })

  return acc;
}, []);

CodePudding user response:

You can improve your method like this.

const nestedResult = objArray.map(
  ({ customFieldId, fieldCode, label, values }) => {
    if (!values) {
      return;
    }
    return values.map((item) => {
      return {
        value: `${customFieldId}-${fieldCode}-${item.value}`,
        text: `${fieldCode} - ${label} - ${item.label}`
      };
    });
  }
);

const finalResult = [].concat(...nestedResult);

console.log(finalResult);
  • Related