javascript - 數(shù)組去重的問題
問題描述
假設現(xiàn)在有一個對象數(shù)組
arr=[ { id:1, content:’a’ },{ id:2, content:’b’ },{ id:2, content:’c’ },{ id:3, content:’d’ },{ id:3, content:’e’ },{ id:3, content:’f’ },{ id:3, content:’g’ },{ id:4, content:’h’ },]
我想去掉相同的id 然后保留各個id的最后一項
arr=[ { id:1, content:’a’ },{ id:2, content:’c’ },{ id:3, content:’g’ },{ id:4, content:’h’ },]
有什么好一點的方法嘛。。
問題解答
回答1:按慣例,ES6 代碼const result = arr.reduce((r, t) => { // 在結果中查找 index, // 如果找到,更新該位置的對象引用 // 找到則加一個 var i = r.findIndex(m => m.id === t.id); if (i >= 0) {r[i] = t; } else {r.push(t); } return r;}, []);
這里有一個問題,findIndex 至少有兩個瀏覽器不支持,所以,如果不支持的話,只好自己寫一個
Array.prototype.findIndex = Array.prototype.findIndex || function(predicate) { for (let i = 0; i < this.length; i++) {if (predicate(this[i])) { return i;} } return -1;};其它解法經(jīng)典解決,用 Map
因為 id 不是字符串,所以使用 ES6 的 Map 類。當數(shù)據(jù)量大的時候,使用查找表,比在列表中線性查找,效率會有顯著的提升。
const result = arr .reduce((m, t) => {const { map, list } = m;var index = map.get(t.id);if (index >= 0) { list[index] = t;} else { map.set(t.id, list.length); list.push(t);}return m; }, {map: new Map(),list: [] }) .list;
其實也可以用對象來代替 map,至少在這個用例中不會有問題。因為沒用 es6 特性,索性完全使用 es5 語法。代碼結構和邏輯與上面那段一樣
var result = arr .reduce(function(m, t) {var index = m.map[t.id];if (index >= 0) { m.list[index] = t;} else { m.map[t.id] = m.list.length; m.list.push(t);}return m; }, {map: {},list: [] }) .list;怪異解法,利用整數(shù) id
因為是整數(shù) id,所以可以直接按這個 id 放在數(shù)組中。如果遇到相同 id,直接就替換了。如果 id 不連續(xù),最后需要把空元素過濾掉
var result = arr .reduce(function(r, t) {r[t.id] = t;return r; }, []) .filter(function(t) { return t; });
這種解法還有個問題,不能保持原數(shù)組的元素順序。然后肯定會有人想到,用 Map 的那個解法也可以把代碼精減成類似的代碼,而不需要搞那么復雜,當然它也同樣可能失去原有順序
const map = arr .reduce((m, t) => {m.set(t.id, t);return m; }, new Map());const result = [...map.values()];
注:以上所有代碼均實際運行通過,運行環(huán)境 Node v8.1.2
回答2:var result = arr.filter(function(val, index) { /** * 使用arr.slice(index + 1)獲取從當前索引下一個元素到數(shù)組最后一個元素組成的數(shù)組 * 使用findIndex在當前項的后面選項中查找是否有和當前項id值相同的選項 */ var index = arr.slice(index + 1).findIndex(function(item) { return item.id === val.id; }); // 如果為-1,則說明后面沒有同名id了,所以這一項可以返回 return index === -1;});console.log(result);
使用箭頭函數(shù)簡化如下:
var result = arr.filter((val, index) => arr.slice(index + 1).findIndex(item => item.id === val.id) === -1);console.log(result);回答3:
這里面已經(jīng)有很多答案了,不過沒有提到Array的內(nèi)置函數(shù)reduceRight,實際上題主的需求,要求保留相同id的最后一位,用reduceRight實現(xiàn)起來很方便。
arr.reduceRight((r,v)=>{ if(!r[0].has(v.id)) r[0].add(v.id) && r[1].unshift(v) return r},[new Set,[]])[1]
reduceRight從你原數(shù)組尾部開始循環(huán)的,我這里的初始值是個數(shù)組,r[0]用來存放id的Set,r[1]存放結果數(shù)組,如果Set里沒有id,那么就添加這個id到Set,并且把這一項放在結果數(shù)組的頭部。
最終很容易的實現(xiàn)了題主的需求,而且順序也能保證。
回答4:function uniq(arr) { var idArr = [],arr2 = [] for (var i = 0, len = arr.length; i < len; i++) {if (arr[i].id in idArr) { arr2.pop() arr2.push(arr[i])} else { idArr.push(arr[i].id) arr2.push(arr[i])} } return arr2}
親測有效
回答5:arr = [ { id: 1, content: ’a’ },{ id: 2, content: ’b’ },{ id: 2, content: ’c’ },{ id: 3, content: ’d’ },{ id: 3, content: ’e’ },{ id: 3, content: ’f’ },{ id: 3, content: ’g’ },{ id: 4, content: ’h’ } ]tmp = []for(k in arr){tmp[arr[k][’id’]] = arr[k][’content’]}arr = []for(k in tmp){arr.push({’id’:+k, ’content’:tmp[k]})}console.log(arr)[ { id: 1, content: ’a’ }, { id: 2, content: ’c’ }, { id: 3, content: ’g’ }, { id: 4, content: ’h’ } ]回答6:
let newArr = [],
result = [], status = false, lastResult = []for (let i = arr.length - 1; i >= 0; i--) { newArr.push(arr[i])}for (let i = 0, len = newArr.length; i < len; i++) { if (result.length == 0) {result.push(newArr[0]) } for (let j = 0; j < result.length; j++) {if (newArr[i].id == result[j].id) { console.log(newArr[i]) status = true} } if (!status) {result.push(newArr[i]) } status = false}for (let i = result.length - 1; i >= 0; i--) { lastResult.push(result[i])}console.log(lastResult) //為去掉相同的id 然后保留各個id的最后一項回答7:
var arr = [ ... ]; // 這個為給定的數(shù)組var obj = {}; // 定義一個對象存儲arr.forEach(function(v) { obj[v.id] = v; // 不管如何,直接將數(shù)組賦值給obj中下標為v.id的項,這樣對應的v.id的值到最后必然是同ID最后一項});// 下面考慮兼容性給出新語法和常規(guī)語法// 新語法,Object.values部分瀏覽器版本不支持var result = Object.values(obj);// 常規(guī)語法,用Array.map實現(xiàn)Object.values的效果var result = Object.keys(obj).map(function(id) { return obj[id];});回答8:
參考一下
Array.from(arr.reduce((map, el) => map.set(el.id, el), new Map()).values())回答9:
你可以參考我博客寫的,我博客上寫了8中方法。http://alfierichou.top/2017/0...
相關文章:
1. php - mysql 模糊搜索問題2. 求救一下,用新版的phpstudy,數(shù)據(jù)庫過段時間會消失是什么情況?3. html - 爬蟲時出現(xiàn)“DNS lookup failed”,打開網(wǎng)頁卻沒問題,這是什么情況?4. java - idea創(chuàng)建多modules項目后,tomcat啟動失敗5. php - 微信開發(fā)驗證服務器有效性6. [python2]local variable referenced before assignment問題7. javascript - 求幫助 , ATOM不顯示界面!!!!8. javascript - js setTimeout在雙重for循環(huán)中如何使用?9. python中怎么對列表以區(qū)間進行統(tǒng)計?10. javascript - 我的站點貌似被別人克隆了, google 搜索特定文章,除了域名不一樣,其他的都一樣,如何解決?
