从两个不同的对象数组中选择数据以创建新的对象数组

时间:2020-04-29 14:54:38

标签: javascript arrays object

我有以下对象数组:

const formulas =
[
    { "formulaID": "1", "versionID": 1, "formulaClass": 3, "formulaType": "34", "outputName": "Chocolate Milk 2%" },
    { "formulaID": "4", "versionID": 1, "formulaClass": 3, "formulaType": "17", "outputName": "Hazelnut Creamer" },
    { "formulaID": "6", "versionID": 1, "formulaClass": 3, "formulaType": "23", "outputName": "White Milk 2%" }
];

const yields =
[
    { "formulaID": "4", "versionID": 1, "yieldFactor": 0.93 },
    { "formulaID": "4", "versionID": 2, "yieldFactor": 0.98 },
    { "formulaID": "6", "versionID": 1, "yieldFactor": 0.95 },
    { "formulaID": "7", "versionID": 1, "yieldFactor": 0.85 }
];

,并尝试以编程方式创建此输出:

const result =
[
    { "formulaID": "7", "versionID": 1, "yieldFactor": 0.85, "outputName": "" },
    { "formulaID": "4", "versionID": 1, "yieldFactor": 0.93, "outputName": "Hazelnut Creamer" },
    { "formulaID": "4", "versionID": 2, "yieldFactor": 0.98, "outputName": "" },
    { "formulaID": "6", "versionID": 1, "yieldFactor": 0.95, "outputName": "White Milk 2%" }
];

this post的帮助下,我编写了以下代码:

const result = yields.map(yld => ({
    formulaID: yld.formulaID,
    versionID: yld.versionID,
    yieldFactor: yld.yieldFactor,
    outputName: formulas.filter(f => (f.formulaID + '-' + f.versionID).includes(yld.formulaID + '-' + yld.versionID))
}));

console.log(result);

它接近预期的结果,但是我不确定如何仅隔离outputName。在其当前状态下,它给出了找到匹配项的整个数组。在源数据的原始数组之间没有匹配的情况下,如何仅显示outputName进行匹配,而在outputName的情况下显示空字符串?

编辑- 当前输出如下所示: enter image description here

2 个答案:

答案 0 :(得分:0)

使用.filter将始终返回满足您条件的公式数组,因此您需要先检查它是否给出结果,然后仅从其结果中检索.outputName

可能是这样的:

const result = yields.map(yld => {
  const targetFormulas = formulas.filter(f => (f.formulaID + '-' + f.versionID).includes(yld.formulaID + '-' + yld.versionID));
  const outputName = targetFormulas.length ? targetFormulas.map(f => f.outputName).join(',') : ''
  return {
    formulaID: yld.formulaID,
    versionID: yld.versionID,
    yieldFactor: yld.yieldFactor,
    outputName
  }
});

如果有1个以上,我已经使用.join(',')返回以逗号分隔的outputNames。
如果您确定只会传回1,则可以 targetFormulas.map(f => f.outputName)[0]

这将返回以下结果

[
   {
      "formulaID":"4",
      "versionID":1,
      "yieldFactor":0.93,
      "outputName":"Hazelnut Creamer"
   },
   {
      "formulaID":"4",
      "versionID":2,
      "yieldFactor":0.98,
      "outputName":""
   },
   {
      "formulaID":"6",
      "versionID":1,
      "yieldFactor":0.95,
      "outputName":"White Milk 2%"
   },
   {
      "formulaID":"7",
      "versionID":1,
      "yieldFactor":0.85,
      "outputName":""
   }
]

答案 1 :(得分:0)

在映射元素时,尝试对reduce集合使用Map方法以使O(1)映射:

const uniqueUtems = new Map(formulas.map(s=>[s.formulaID, s.outputName]));

const result = yields.reduce((a, {formulaID, ...rest}) => {
    a.push({ formulaID , outputName: uniqueUtems.get(formulaID) || '', ...rest });
    if (uniqueUtems.has(formulaID))
        uniqueUtems.delete(formulaID)
    return a;
}, []);

console.log(result);

一个例子:

const formulas =
[
    { "formulaID": "1", "versionID": 1, "formulaClass": 3, "formulaType": "34", "outputName": "Chocolate Milk 2%" },
    { "formulaID": "4", "versionID": 1, "formulaClass": 3, "formulaType": "17", "outputName": "Hazelnut Creamer" },
    { "formulaID": "6", "versionID": 1, "formulaClass": 3, "formulaType": "23", "outputName": "White Milk 2%" }
];

const yields =
[
    { "formulaID": "4", "versionID": 1, "yieldFactor": 0.93 },
    { "formulaID": "4", "versionID": 2, "yieldFactor": 0.98 },
    { "formulaID": "6", "versionID": 1, "yieldFactor": 0.95 },
    { "formulaID": "7", "versionID": 1, "yieldFactor": 0.85 }
];

const uniqueUtems = new Map(formulas.map(s=>[s.formulaID, s.outputName]));

const result = yields.reduce((a, {formulaID, ...rest}) => {
    a.push({ formulaID , outputName: uniqueUtems.get(formulaID) || '', ...rest });
    if (uniqueUtems.has(formulaID))
        uniqueUtems.delete(formulaID)
    return a;
}, []);

console.log(result);

...rest is:

rest参数语法允许我们表示一个不确定的数字 参数作为数组。