通过匹配字段映射两个对象数组来更新数组

时间:2020-09-10 16:33:13

标签: javascript arrays ecmascript-6

我有一个具有以下结构的对象数组:

let source1 = [
  {
    s1prop1: "val1",
    s1prop2: ["test1", "test2"]
  },
  {
    s1prop1: "val2",
    s1prop2: []
  }
];

let source2 = [
  {
    s2prop1: "test1",
    s2prop2: "finalVal1"
  },
  {
    s2prop1: "test2",
    s2prop2: "finalVal2"
  },
  {
    s2prop1: "test3",
    s2prop2: "finalVal3"
  }
];

基本上需要遍历source1,然后基于s1prop2数组的项目,需要从第二个对象数组(即s2prop2中选择对应的source2然后使用匹配的值更新source1。如果s1prop2的值是空数组,请跳过它。对象的结果数组应该看起来像

let result = [
  {
    s1prop1: "val1",
    //fetching the s2prop2 value from source2 based on s1prop1 array items by matching s2prop1, i.e.,test1 and test2 
    s1prop2: ["finalVal1", "finalVal2"]
  },
  {
    s1prop1: "val2",
    s1prop2: []
  }
];

我尝试过的事情:

let result = source1.map((e, i) => {
  let temp = source2.find((element) => element === e.s2prop1);
  return e;
});

3 个答案:

答案 0 :(得分:1)

您只需要将数组的每个值更改为与第二个数组相对应的一个值即可

let result = source1.map((e, i) => {
    e.s1prop2 = e.s1prop2.map( o => {
        return (source2.find((element) => element.s2prop1 === o) || {}).s2prop2 || null;
    })
    return e;
});

let source1 = [
  {
    s1prop1: "val1",
    s1prop2: ["test1", "test2"]
  },
  {
    s1prop1: "val2",
    s1prop2: []
  }
];

let source2 = [
  {
    s2prop1: "test1",
    s2prop2: "finalVal1"
  },
  {
    s2prop1: "test2",
    s2prop2: "finalVal2"
  },
  {
    s2prop1: "test3",
    s2prop2: "finalVal3"
  }
];
let result = source1.map((e, i) => {
    e.s1prop2 = e.s1prop2.map( o => {
        return (source2.find((element) => element.s2prop1 === o) || {}).s2prop2 || null;
    })
    return e;
});
console.log(result);

答案 1 :(得分:1)

您需要映射source元素中的s1prop2数组,并通过搜索s1prop2的相应元素,使用该数组在result元素中构造source2属性。 / p>

let source1 = [{
    s1prop1: "val1",
    s1prop2: ["test1", "test2"]
  },
  {
    s1prop1: "val2",
    s1prop2: []
  }
];

let source2 = [{
    s2prop1: "test1",
    s2prop2: "finalVal1"
  },
  {
    s2prop1: "test2",
    s2prop2: "finalVal2"
  },
  {
    s2prop1: "test3",
    s2prop2: "finalVal3"
  }
];

let result = source1.map(obj => ({
  ...obj,
  s1prop2: obj.s1prop2.map(p => source2.find(el => el.s2prop1 == p).s2prop2)
}));

console.log(result);

如果source2是使用s2prop1值作为属性名称的对象,而不是必须搜索的数组,事情会容易得多。

答案 2 :(得分:1)

您可以使用功能Array.prototype.reduce进行分组,并使用功能Object.values提取分组的对象。

let source1 = [  {    s1prop1: "val1",    s1prop2: ["test1", "test2"]  },  {    s1prop1: "val2",    s1prop2: []  }],
    source2 = [  {    s2prop1: "test1",    s2prop2: "finalVal1"  },  {    s2prop1: "test2",    s2prop2: "finalVal2"  },  {    s2prop1: "test3",    s2prop2: "finalVal3"  }],
    result = Object.values(source1.reduce((r, {s1prop1, s1prop2}) => {
      let properties = source2.reduce((a, {s2prop1, s2prop2}) => s1prop2.includes(s2prop1) ? a.concat(s2prop2) : a, []);
      (r[s1prop1] || (r[s1prop1] = {s1prop1, s1prop2: []})).s1prop2.push(...properties);
      return r;
    }, {}));

console.log(result);