從一個數組中刪除重複對象

一、簡單的數組去重
 
能夠借用數組的 filter()方法和indexOf()方法,因爲 indexOf(item) 返回的是數組中第一個item的索引,因此能夠藉此實現數組元素去重的功能
const names = ['張三', '李四', '張三'];

function getUnique(arr) {
  return arr.filter((item, index) => arr.indexOf(item) === index)
}

getUnique(names); // ["張三", "李四"]

 

二、從數組中刪除重複的對象
 
若是數組的元素是對象,就不那麼簡單了。衆所周知,對象是引用類型,比較兩個對象不是比較對象的屬性和值而是比較對象的地址值
 
以下例所示,數組首尾兩個元素看起來是如出一轍的,可是用前面的方法無法去重
const goodsList = [
  {
    goodsCode: '2611201047G',
    goodsName: '華爲暢享9 Plus 4GB+128GB 極光紫 雙卡 全網通版 JKM-AL00'
  },
  {
    goodsCode: '2611201418G',
    goodsName: 'HUAWEInova5i 8GB+128GB 蘇音藍 全網通版'
  },
  {
    goodsCode: '2611201047G',
    goodsName: '華爲暢享9 Plus 4GB+128GB 極光紫 雙卡 全網通版 JKM-AL00'
  }
]


getUnique(goodsList);  // 返回的依然是goodsList

 

這裏能夠藉助JSON.stringify() 方法把一個對象轉成string類型來作比較
function getUnique2(arr) {
  const map = {};
  // 一、把數組元素做爲對象的鍵存起來(這樣就算有重複的元素,也會相互替換掉)
  arr.forEach(item => map[JSON.stringify(item)] = item);
  
  // 二、再把對象的值抽成一個數組返回即爲不重複的集合
  return Object.keys(map).map(key => map[key])
}

getUnique2(goodsList); 
/*
  [
    {goodsCode: "2611201047G", goodsName: "華爲暢享9 Plus 4GB+128GB 極光紫 雙卡 全網通版 JKM-AL00"},
    {goodsCode: "2611201418G", goodsName: "HUAWEInova5i 8GB+128GB 蘇音藍 全網通版"}
  ]
*/

 

可是這裏有一個問題,假如把 goodsList 中最後一個元素的 goodsCode 和 goodsName調換一下順序,就無法去重了數組

const goodsList = [ // 注意比較首尾元素對象中內部屬性的順序
  {
    goodsCode: '2611201047G',
    goodsName: '華爲暢享9 Plus 4GB+128GB 極光紫 雙卡 全網通版 JKM-AL00'
  },
  {
    goodsCode: '2611201418G',
    goodsName: 'HUAWEInova5i 8GB+128GB 蘇音藍 全網通版'
  },
  { 
    goodsName: '華爲暢享9 Plus 4GB+128GB 極光紫 雙卡 全網通版 JKM-AL00',
    goodsCode: '2611201047G'
  }
]

function getUnique3(arr) {
  const map = {};

  arr.forEach(item => {
    const obj = {};
    // 一、把數組中的元素(對象)的鍵名抽成一個數組而後排序
    // 二、生成一個按照鍵名排序好的對象
    Object.keys(item).sort().map(key => obj[key] = item[key]);

    // 三、把新生成的對象做爲對象的鍵存起來
    map[JSON.stringify(obj)] = item;
  });
  
  // 四、再把新對象的鍵名抽成一個數組返回即爲不重複的集合
  return Object.keys(map).map(key => JSON.parse(key));
}

console.log(getUnique3(goodsList)); 
/*
  [
    {goodsCode: "2611201047G", goodsName: "華爲暢享9 Plus 4GB+128GB 極光紫 雙卡 全網通版 JKM-AL00"},
    {goodsCode: "2611201418G", goodsName: "HUAWEInova5i 8GB+128GB 蘇音藍 全網通版"}
  ]
*/

 

除了上面那樣,經過把對象的屬性名排序來處理之外,還能夠藉助JSON.stringify()的replacer參數來實現
JSON.stringify(value[, replacer [, space]])

value:將要序列化成 一個 JSON 字符串的值。

replacer:若是 replacer 是一個數組,數組的值表明將被序列化成 JSON 字符串的屬性名

 

也就是說,能夠經過 JSON.stringify的第二個參數指定按必定的順序來序列化,例如spa

const goodsList = [ // 注意比較首尾元素對象中內部屬性的順序
  {
    goodsCode: '2611201047G',
    goodsName: '華爲暢享9 Plus 4GB+128GB 極光紫 雙卡 全網通版 JKM-AL00'
  },
  {
    goodsCode: '2611201418G',
    goodsName: 'HUAWEInova5i 8GB+128GB 蘇音藍 全網通版'
  },
  { 
    goodsName: '華爲暢享9 Plus 4GB+128GB 極光紫 雙卡 全網通版 JKM-AL00',
    goodsCode: '2611201047G'
  }
]

console.log(JSON.stringify(goodsList, ['goodsName', 'goodsCode']));
/*
  [
    {"goodsName":"華爲暢享9 Plus 4GB+128GB 極光紫 雙卡 全網通版 JKM-AL00","goodsCode":"2611201047G"},
    {"goodsName":"HUAWEInova5i 8GB+128GB 蘇音藍 全網通版","goodsCode":"2611201418G"},
    {"goodsName":"華爲暢享9 Plus 4GB+128GB 極光紫 雙卡 全網通版 JKM-AL00","goodsCode":"2611201047G"}
  ]
*/

 

因而可知,只須要把 getUnique2() 稍做修改,就能夠產生最佳的解決方案了code

function getUnique2(arr) {
  const map = {};
  // 一、把數組元素做爲對象的鍵存起來(這樣就算有重複的元素,也會相互替換掉)
  arr.forEach(item => map[JSON.stringify(item, ['goodsCode', 'goodsName'])] = item);
  
  // 二、再把新對象的鍵名抽成一個數組返回即爲不重複的集合
  return Object.keys(map).map(key => JSON.parse(key))
}

console.log(getUnique2(goodsList)); 
/*
  [
    {goodsCode: "2611201047G", goodsName: "華爲暢享9 Plus 4GB+128GB 極光紫 雙卡 全網通版 JKM-AL00"},
    {goodsCode: "2611201418G", goodsName: "HUAWEInova5i 8GB+128GB 蘇音藍 全網通版"}
  ]
*/
相關文章
相關標籤/搜索