每个对象的标签值对象

Label-Value object for each object

我有以下内容:

const itemsArr = [{
    id: 0,
    baseDetails: {
      modelNames: ["Atoga3"],
      companies: ['Sunafga']
    }
  },
  {
    id: 1,
    baseDetails: {
      modelNames: ["Bisuda-X23", "Oidas"],
      companies: ["Sunafga", "Kemaite"]
    }
  },
  {
    id: 2,
    baseDetails: {
      modelNames: ["Zarusa-M3", "Kalasi-W"],
      companies: ["Abado", "Sunafga"]
    }
  }
]

我想要实现的是每个公司都有一个数组 -> modelName 组合。

所以它应该看起来像:

[{
    value: 'sunafga',
    label: 'Sunafga',
    children: [{
        value: 'atoga3',
        label: 'Atoga3'
      },
      {
        value: 'bisuda-x23',
        label: 'bisuda-X23'
      },
      {
        value: 'oidas',
        label: 'Oidas'
      },
      {
        value: 'zarusa-m3',
        label: 'Zarusa-M3'
      },
      {
        value: 'valasi-W',
        label: 'Kalasi-W'
      }
    ]
  },

  {
    value: 'kemaite',
    label: 'Kemaite',
    children: [{
        value: 'bisuda-x23',
        label: 'bisuda-X23'
      },
      {
        value: 'oidas',
        label: 'Oidas'
      },
    ]
  },
]

您可能需要在这里进行两步转换,一步转换为有用的结构以删除所有这些重复项,然后将其轻推到您想要的结构中

const itemsArr = [{
    id: 0,
    baseDetails: {
      modelNames: ["Atoga3"],
      companies: ['Sunafga']
    }
  },
  {
    id: 1,
    baseDetails: {
      modelNames: ["Bisuda-X23", "Oidas"],
      companies: ["Sunafga", "Kemaite"]
    }
  },
  {
    id: 2,
    baseDetails: {
      modelNames: ["Zarusa-M3", "Kalasi-W"],
      companies: ["Abado", "Sunafga"]
    }
  }
]

// transform to a useful structure for removing duplicates
const companyMap = itemsArr.reduce((acc, val) => {
  val.baseDetails.companies.forEach(c => {
    acc[c] = val.baseDetails.modelNames.reduce((a, m) => Object.assign(a, {[m]: true}), (acc[c] || {}))
  });
  return acc
}, {})

// transform your useful structure to the desired one
const newArray = Object.entries(companyMap).map(([company, models]) => {
  return {
    value: company.toLowerCase(),
    label: company,
    children: Object.keys(models).map(model => ({label: model, value: model.toLowerCase()}))
  }
})
console.log(newArray)

如果你想一直减少,你可以使用这个作为你的中间转换:

const companyMap = itemsArr.reduce((cMap, item) => 
  Object.assign(cMap,
    item.baseDetails.companies.reduce((iMap, c) => 
      Object.assign(iMap,
        {[c]: item.baseDetails.modelNames.reduce((a, m) => Object.assign(a, {[m]: true}), (cMap[c] || {}))}
      )
    , {})
  )
, {})

如果不强制使用 reduce,这里有一个解决方案:

const itemsArr = [{
    id: 0,
    baseDetails: {
      modelNames: ["Atoga3"],
      companies: ['Sunafga']
    }
  },
  {
    id: 1,
    baseDetails: {
      modelNames: ["Bisuda-X23", "Oidas"],
      companies: ["Sunafga", "Kemaite"]
    }
  },
  {
    id: 2,
    baseDetails: {
      modelNames: ["Zarusa-M3", "Kalasi-W"],
      companies: ["Abado", "Sunafga"]
    }
  }
];

const result = [];
itemsArr.forEach(item => {
  item.baseDetails.companies.forEach(company => {
    let companyEntry = result.find(resultEntry => resultEntry.label === company);
    if (!companyEntry) {
      companyEntry = {
        label: company,
        value: company.toLowerCase(),
        children: []
      };
      result.push(companyEntry);
    }
    const companyChildren = companyEntry.children;
    item.baseDetails.modelNames.forEach(modelName => {
      if (!companyChildren.find(companyModel => companyModel.label === modelName)) {
        companyChildren.push({
          label: modelName,
          value: modelName.toLowerCase()
        });
      }
    });
  });
});
console.log(result);