Javascript 如何通过es6合并两个相交阵列

Javascript 如何通过es6合并两个相交阵列,javascript,angular,typescript,ecmascript-6,Javascript,Angular,Typescript,Ecmascript 6,我有两个具有属性的数组:minValue,maxValue,avgValue。我想写一个非常简洁的方法来识别数组中哪些对象匹配(displayName),然后将新数组的值分配给旧数组(minPrice、maxPrice、avgPrice) 到目前为止我有这个代码 export interface Player { displayName: string; MinPrice: number; MaxPrice: number; AvgPrice: number;}

我有两个具有属性的数组:
minValue
maxValue
avgValue
。我想写一个非常简洁的方法来识别数组中哪些对象匹配(displayName),然后将新数组的值分配给旧数组(minPrice、maxPrice、avgPrice)

到目前为止我有这个代码

export interface Player {
    displayName: string;
    MinPrice: number;
    MaxPrice: number;
    AvgPrice: number;}

export const MERGE_PLAYER_STATS = (playerStat: Player[], auctionStat: Player[]): any => {
      const reducer = (playerStat, auctionStat) => {
        playerStat.MinPrice = auctionStat.minPrice,
        playerStat.MaxPrice = auctionStat.maxPrice,
        playerStat.AvgPrice = auctionStat.avgPrice,
        playerStat.Team = auctionStat.team;
     }
      return reducer(playerStat, auctionStat =>
        filter(auctionStat, playerStat => auctionStat.displayName.includes(playerStat.displayName)));
}


Input: two different set of player arrays that have common display Names.  
playerStat: [] = [];
auctionStat: [] = [];

playerStat.push( {
displayName: "Josh Allen",
minPrice: "",
maxPrice: "",
avgPrice: ""
}, 
{
displayName: "No One",
minPrice: "",
maxPrice: "",
avgPrice: ""
});

auctionStat.push( {
displayName: "Josh Allen",
minPrice: 1,
maxPrice: 2,
avgPrice: 1
}, 
{
displayName: "No One 2",
minPrice: 1,
maxPrice: 1,
avgPrice: 2
});
输出应该只有Josh Allen统计数据分别从空白值更新为1,2,1

请让我知道你的清洁方法。仅供参考,此代码没有返回我想要的内容。

使用Object.assign()


例如:oldArray=Object.assign(oldArray,newArray)

简单的方法是编写一个映射函数,根据匹配的键复制新对象

给定一个接口:

interface MyInterface {
  key: string;
  value: number;
}
和两个阵列:

const existingArray: MyInterface[] = [
  { key: 'a', value: 1 },
  { key: 'b', value: 2 },
  { key: 'c', value: 3 }
];

const newArray: MyInterface[] = [
  { key: 'b', value: 20 },
  { key: 'c', value: 30 },
  { key: 'd', value: 40 }
];
预期产出

我想用键匹配的
newArray
中的值更新
existingArray

  • 如果在
    newArray
    中找不到值,则现有项将保持不变
  • 如果在
    newArray
    中找到新值,则不会将其合并到
    oldArray
  • 所有属性值都将被覆盖
我的预期产出是:

const expected = [
  { key: 'a', value: 1 },
  { key: 'b', value: 20 },
  { key: 'c', value: 30 }
];
解决方案

我将通过使用这个合并函数来实现这一点。它只是一个javascript数组映射:

private merge<T>(existing: T[], updated: T[], getKey: (t: T) => string): T[] {
  // start with the existing array items
  return existing.map(item => {
    // get the key using the callback
    const key: string = getKey(item);
    // find the matching item by key in the updated array
    const matching: T = updated.find(x => getKey(x) === key);
    if (matching) {
      // if a matching item exists, copy the property values to the existing item
      Object.assign(item, matching);
    }
    return item;
  });
}
演示:

一句警告

对于非常大的阵列,这将无法很好地扩展。如果您使用的是大型数组,我会通过创建
Map
类型的索引进行优化,以保持循环数固定。此实现超出了此问题的范围

编辑:

如果只想更新特定值,可以传入更新回调:

private merge<T>(existing: T[], updated: T[], getKey: (t: T) => string, 
  update: (item, matching) => void
): T[] {
  return existing.map(item => {
    const key: string = getKey(item);
    const matching: T = updated.find(x => getKey(x) === key);
    if (matching) {
      update(item, matching);
    }
    return item;
  });
}

请共享两个阵列您的意思是,获取重复的对象?不。我想查找具有相同显示名称的相交对象。并重新分配第一个数组的值和第二个数组(minPrice、maxPrice、avgPrice)的值。@Christopher请添加任何相关代码,使问题更清楚地传达给question@ChristopherYou不特别!示例输入和预期输出会很好。把它想象成编写一个目前失败的单元测试,你想得到一些帮助让它通过。我知道问题不清楚,但这是如何解决问题的?这只会在匹配索引处用newArray中的值覆盖oldArray。Object.assign不能自动理解数组内容的内部结构。@KurtHamilton我写了一个减缩器并试图对其进行过滤,这是正确的吗?要将值从新数组复制到旧数组,这是一种方法,它会识别键,如果有额外的键,它也会添加,而这段代码可能会提供OP问题的解决方案,强烈建议您提供有关此代码为什么和/或如何回答问题的其他上下文。从长远来看,纯代码的答案通常会变得毫无用处,因为未来遇到类似问题的观众无法理解解决方案背后的原因。实际上,我想用匹配的键更新数组中的每个对象。对于您的解决方案,我必须在合并调用中使用for循环。这听起来像是最好的解决方案吗?如果我理解正确,我已经用建议的解决方案更新了我的答案。
const merged = this.merge(existingArray, newArray, x => x.key);
private merge<T>(existing: T[], updated: T[], getKey: (t: T) => string, 
  update: (item, matching) => void
): T[] {
  return existing.map(item => {
    const key: string = getKey(item);
    const matching: T = updated.find(x => getKey(x) === key);
    if (matching) {
      update(item, matching);
    }
    return item;
  });
}
const merged = this.merge(existingArray, newArray, x => x.key, 
  (item, matching) => item.value = matching.value);