减少数组以从左到右删除重复的 matchId 条目

reduce down array to remove duplicate matchId entries from left to right

当用户更新 matchId 的分数时,我将一个对象推送到一个数组,我希望我的最终数组删除所有最旧的 matchId 副本,所以从索引0到最后,有办法吗?

我有这个:

cleanData =
    0: {matchId: "271691", homeTeamScore: "1", awayTeamScore: "1"}
    1: {matchId: "271692", homeTeamScore: "1", awayTeamScore: "1"}
    2: {matchId: "271700", homeTeamScore: "1", awayTeamScore: "1"}
    3: {matchId: "271691", homeTeamScore: "6", awayTeamScore: "6"}
    4: {matchId: "271691", homeTeamScore: "8", awayTeamScore: "8"}
    5: {matchId: "271691", homeTeamScore: "8", awayTeamScore: "8"}
    6: {matchId: "271691", homeTeamScore: "8", awayTeamScore: "0"}

我想要这个:

0: {matchId: "271692", homeTeamScore: "1", awayTeamScore: "1"}
1: {matchId: "271700", homeTeamScore: "1", awayTeamScore: "1"}
2: {matchId: "271691", homeTeamScore: "8", awayTeamScore: "0"}

我的代码:

saveResult(data: any, pushMatchId: any) {
    if (this.savedResults) {
      let cleanData = this.savedResults.map((item) => {
        return {
          matchId: item.matchId,
          homeTeamScore: item.homeTeamScore,
          awayTeamScore: item.homeTeamScore,
        };
      });
      data.map((item) => {
        cleanData.push(item);
      });
      this.db.collection("users").doc(this.user.uid).update({
        results: cleanData,
      });
    } else {
      this.db.collection("users").doc(this.user.uid).set({
        results: data,
      });
    }

  }

一个选项是创建一个 Set 来跟踪您之前见过的 matchId 个字符串,反转数组,并根据是否见过该元素来过滤它。此解决方案仅在保证订购商品时有效。

const input = [
  {matchId: "271691", homeTeamScore: "1", awayTeamScore: "1"},
  {matchId: "271692", homeTeamScore: "1", awayTeamScore: "1"},
  {matchId: "271700", homeTeamScore: "1", awayTeamScore: "1"},
  {matchId: "271691", homeTeamScore: "6", awayTeamScore: "6"},
  {matchId: "271691", homeTeamScore: "8", awayTeamScore: "8"},
  {matchId: "271691", homeTeamScore: "8", awayTeamScore: "8"},
  {matchId: "271691", homeTeamScore: "8", awayTeamScore: "0"}
];

const exists = new Set();

const unique = [...input].reverse().filter(({matchId}) => {
  if (!exists.has(matchId)) {
    exists.add(matchId);
    return true;
  }
  return false;
})

console.log(unique);

删除重复项听起来像是解决了发生的问题。为什么不完全阻止添加重复项?

在添加到数组之前,检查 matchId 是否已经在数组中,如果过滤掉则添加新数据。如果没有,添加新数据

由于数组中的最新对象是您想要的对象,因此您可以使用 reduceRight() 并将最终数组中尚未存在的匹配项添加到最终结果中,例如:

let matches = [
  { matchId: "271691", homeTeamScore: "1", awayTeamScore: "1" },
  { matchId: "271692", homeTeamScore: "1", awayTeamScore: "1" },
  { matchId: "271700", homeTeamScore: "1", awayTeamScore: "1" },
  { matchId: "271691", homeTeamScore: "6", awayTeamScore: "6" },
  { matchId: "271691", homeTeamScore: "8", awayTeamScore: "8" },
  { matchId: "271691", homeTeamScore: "8", awayTeamScore: "8" },
  { matchId: "271691", homeTeamScore: "8", awayTeamScore: "0" },
];

let result = matches.reduceRight(
  (p, c) => (!p.find((o) => o.matchId === c.matchId) ? [...p, c] : p),
  []
);

console.log(result);

或更优化的方法,将最新的 matchIds 存储在地图中:

let matches = [
  { matchId: "271691", homeTeamScore: "1", awayTeamScore: "1" },
  { matchId: "271692", homeTeamScore: "1", awayTeamScore: "1" },
  { matchId: "271700", homeTeamScore: "1", awayTeamScore: "1" },
  { matchId: "271691", homeTeamScore: "6", awayTeamScore: "6" },
  { matchId: "271691", homeTeamScore: "8", awayTeamScore: "8" },
  { matchId: "271691", homeTeamScore: "8", awayTeamScore: "8" },
  { matchId: "271691", homeTeamScore: "8", awayTeamScore: "0" },
];

let matchIds = new Map();
let result = matches.reduceRight((p, c) => {
  if (!matchIds.get(c.matchId)) {
    matchIds.set(c.matchId, true);
    return [...p, c];
  }
  return p;
}, []);

console.log(result);

如果您想事先检查是否已经存在具有特定 ID 的匹配项并在添加最新的之前将其过滤掉,您可以执行以下操作:

let matches = [
  { matchId: "271691", homeTeamScore: "1", awayTeamScore: "1" },
  { matchId: "271692", homeTeamScore: "1", awayTeamScore: "1" },
  { matchId: "271700", homeTeamScore: "1", awayTeamScore: "1" },
];

let addMatch = (match) => {
  matches = matches.filter(({
    matchId
  }) => matchId !== match.matchId);
  return matches.push(match), matches;
};

let latest = { matchId: "271691", homeTeamScore: "6", awayTeamScore: "6" };

addMatch(latest); // Add the latest match, replace if there was already a score

console.log(matches);

你可以这样解决

data = [
  { matchId: "271692", homeTeamScore: "1", awayTeamScore: "1" },
  { matchId: "271700", homeTeamScore: "1", awayTeamScore: "1" },
  { matchId: "271691", homeTeamScore: "8", awayTeamScore: "0" },
];

function pushToData(data, newObject) {

  for (let i = 0; i < data.length; i++) {
    // debugger;
    if (data[i].matchId === newObject.matchId) {
      data.splice(i, 1);
      data.push(newObject);
      return;
    }
  }
}

console.log(JSON.stringify(data));
pushToData(data, { matchId: "271691", homeTeamScore: "8", awayTeamScore: "999" });
console.log(JSON.stringify(data));

如果这个想法真的是要删除旧分数,这里是一个解决方案:

const input = 
      [ { matchId: "271691", homeTeamScore: "1", awayTeamScore: "1" } 
      , { matchId: "271692", homeTeamScore: "1", awayTeamScore: "1" } 
      , { matchId: "271700", homeTeamScore: "1", awayTeamScore: "1" } 
      , { matchId: "271691", homeTeamScore: "6", awayTeamScore: "6" } 
      , { matchId: "271691", homeTeamScore: "8", awayTeamScore: "8" } 
      , { matchId: "271691", homeTeamScore: "8", awayTeamScore: "8" } 
      , { matchId: "271691", homeTeamScore: "8", awayTeamScore: "0" } 
      ] 

let matchList = new Set()
for (let i=input.length;i--;)
  {
  if (matchList.has(input[i].matchId)) { input.splice(i, 1)  }
  else                                 { matchList.add(input[i].matchId) }
  }

console.log( input  )