Home > database >  complex object manipulation
complex object manipulation

Time:12-08

I have an array:

const arr = [
    {
        countries : {countryCode :"US", value: true},
        vendors:  [{vendorName: 'TES', value: true}, {vendorName: 'HPEFS', value: true}]
    },
    {
        countries : {countryCode :"CA", value: true},
        vendors:  [{vendorName: 'TES', value: true}, {vendorName: 'HPEFS', value: false}]
    }
];

expected result:  [{vendor: "TES", countries: [US, CA]}, {vendor: "HPEFS", countries: [US]}]

Any idea is appreciated, Thanks in advance

CodePudding user response:

You can easily achieve the result using Map and forEach

const arr = [
  {
    countries: { countryCode: "US", value: true },
    vendors: [
      { vendorName: "TES", value: true },
      { vendorName: "HPEFS", value: true },
    ],
  },
  {
    countries: { countryCode: "CA", value: true },
    vendors: [
      { vendorName: "TES", value: true },
      { vendorName: "HPEFS", value: false },
    ],
  },
];

const map = new Map();
arr.forEach(({ countries, vendors }) => {
  const { countryCode, value } = countries;
  vendors.forEach((o) => {
    if (o.value) {
      !map.has(o.vendorName)
        ? map.set(o.vendorName, [countryCode])
        : map.get(o.vendorName).push(countryCode);
    }
  });
});
const result = [];
for (let [vendor, countries] of map) result.push({ vendor, countries });
console.log(result);
/* This is not a part of answer. It is just to give the output full height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Here is the solution:

const arr = [
    {
        countries: { countryCode: "US", value: true },
        vendors: [{ vendorName: 'TES', value: true }, { vendorName: 'HPEFS', value: true }]
    },
    {
        countries: { countryCode: "CA", value: true },
        vendors: [{ vendorName: 'TES', value: true }, { vendorName: 'HPEFS', value: false }]
    }
];

// expected result:  [{vendor: "TES", countries: [US, CA]}, {vendor: "HPEFS", countries: [US]}]

const loookup = arr.reduce((acc, curr) => {
    curr.vendors.forEach(item => {
        if (item.value) {
            if (acc[item.vendorName] && !acc[item.vendorName].includes(curr.countries)) {
                acc[item.vendorName] = [...acc[item.vendorName], curr.countries.countryCode]
            } else {
                acc[item.vendorName] = [curr.countries.countryCode]
            }
        }
    })

    return acc;
}, {});

const result = Object.keys(loookup).map(key => {
    return {
        vendor: key,
        countries: loookup[key]
    }
})
console.log(result)
/* This is not a part of answer. It is just to give the output full height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related