过滤具有多个相同属性的数组

a f*_*ice 1 javascript arrays lookup reduce data-structures

所以我有一个像这样的值数组

const foodsList = [
  {
    foodOrigin: "Padang",
    foodName: "Nasi Padang",
    originCode: "PDN"
  },
  {
    foodOrigin: "Padang",
    foodName: "Gulai",
    originCode: "PDN"
  },
  {
    foodOrigin: "Padang",
    foodName: "Rendang",
    originCode: "PDN"
  },
  {
    foodOrigin: "Palembang",
    foodName: "Pempek",
    originCode: "PLG"
  },
  {
    foodOrigin: "Palembang",
    foodName: "Tekwan",
    originCode: "PLG"
  },
  {
    foodOrigin: "Yogyakarta",
    foodName: "Gudeg",
    originCode: "YKT"
  }
];
Run Code Online (Sandbox Code Playgroud)

我想过滤数组,所以结果会像这样

const filteredFoodsList = [
  {
    foodOrigin: "Padang",
    originCode: "PDN"
  },
  {
    foodOrigin: "Palembang",
    originCode: "PLG"
  },
  {
    foodOrigin: "Yogyakarta",
    originCode: "YKT"
  }
];
Run Code Online (Sandbox Code Playgroud)

为了达到这个结果,我尝试像下面那样做,但是有没有更干净、更好的方法来做到这一点?(特别是因为我的实际数组的数据包含超过 500 个)

const filteredFoodsList = [];
for (let i = 0; i < foodsList.length; i++) {
  if (i === 0) {
    filteredFoodsList.push({
      originCode: foodsList[i].originCode,
      foodOrigin: foodsList[i].foodOrigin
    });
  }
  let isExist = false;
  for (let j = 0; j < filteredFoodsList.length; j++) {
    if (foodsList[i].originCode === filteredFoodsList[j].originCode) {
      isExist = true;
    }
  }
  if (!isExist) {
    filteredFoodsList.push({
      originCode: foodsList[i].originCode,
      foodOrigin: foodsList[i].foodOrigin
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*hev 5

正如OP所说,应该关注性能,所以..

Map可能是收集独特价值的最快方法。
(我借用了Array.from(map, ([originCode, foodOrigin]) => ({ foodOrigin, originCode }))尼娜的答案,非常优雅)。

但它不会影响性能,因为生成的数组应该非常小。

但她忘记包含一项Map::has()确实可以显着提高性能的检查。

重要的是源数组的迭代速度。一如既往,我认为没有比for(let i = 0; ...)……更快的事情了。

const foodsList=[{foodOrigin:"Padang",foodName:"Gulai",originCode:"PDN"},{foodOrigin:"Padang",foodName:"Rendang",originCode:"PDN"},{foodOrigin:"Palembang",foodName:"Pempek",originCode:"PLG"},{foodOrigin:"Palembang",foodName:"Tekwan",originCode:"PLG"},{foodOrigin:"Yogyakarta",foodName:"Gudeg",originCode:"YKT"}];

const map = new Map;
for (let i = 0; i < foodsList.length; i++) {
    const item = foodsList[i];
    map.has(item.originCode) || map.set(item.originCode, item.foodOrigin);
}

const result = Array.from(map, ([originCode, foodOrigin]) => ({ foodOrigin, originCode }));

console.log(result);
Run Code Online (Sandbox Code Playgroud)

和一个基准:

` Chrome/121
--------------------------------------------------------------------------------------
>                         n=10000     |   n=100000    |   n=1000000    |  n=10000000  
Alexander's solution   1.23x x10k 526 | 1.00x x1k 518 | 1.00x x100 543 | 1.00x x10 554
Nina's improved        1.00x x10k 429 | 1.35x x1k 700 | 1.32x x100 717 | 1.31x x10 727
Peter's solution       1.00x x10k 427 | 1.44x x1k 746 | 1.35x x100 732 | 1.37x x10 760
Nina's solution        1.23x x10k 524 | 1.55x x1k 801 | 1.50x x100 815 | 1.46x x10 811
--------------------------------------------------------------------------------------
https://github.com/silentmantra/benchmark `
Run Code Online (Sandbox Code Playgroud)
` Firefox/122
---------------------------------------------------------------------------------------
>                         n=10000     |    n=100000    |   n=1000000    |  n=10000000  
Alexander's solution   1.00x x10k 355 | 1.00x  x1k 363 | 1.00x x100 383 | 1.00x x10 380
Nina's improved        3.63x  x1k 129 | 3.64x x100 132 | 3.86x  x10 148 | 3.68x  x1 140
Peter's solution       4.00x  x1k 142 | 3.55x x100 129 | 3.39x  x10 130 | 3.95x  x1 150
Nina's solution        4.08x  x1k 145 | 4.16x x100 151 | 3.97x  x10 152 | 4.03x  x1 153
---------------------------------------------------------------------------------------
https://github.com/silentmantra/benchmark `
Run Code Online (Sandbox Code Playgroud)

` Chrome/121
--------------------------------------------------------------------------------------
>                         n=10000     |   n=100000    |   n=1000000    |  n=10000000  
Alexander's solution   1.23x x10k 526 | 1.00x x1k 518 | 1.00x x100 543 | 1.00x x10 554
Nina's improved        1.00x x10k 429 | 1.35x x1k 700 | 1.32x x100 717 | 1.31x x10 727
Peter's solution       1.00x x10k 427 | 1.44x x1k 746 | 1.35x x100 732 | 1.37x x10 760
Nina's solution        1.23x x10k 524 | 1.55x x1k 801 | 1.50x x100 815 | 1.46x x10 811
--------------------------------------------------------------------------------------
https://github.com/silentmantra/benchmark `
Run Code Online (Sandbox Code Playgroud)