2017-10-15 81 views
0

我需要從對象數組中獲取元素,其中該對象的某個屬性(本例中爲name)被複制 - 換句話說,出現在數組中的某個其他對象中。獲取具有重複值的數組中的對象

數據

var data = [ 
    {id:1, name:"sam", userid:"ACD"}, 
    {id:1, name:"ram", userid:"SDC"}, 
    {id:1, name:"sam", userid:"CSTR"} 
]; 

我需要檢查所有的行,並得到所有地方name屬性複製數組值。

預期輸出:

[ 
    {id:1, name:"sam", userid:"ACD"}, 
    {id:1, name:"sam", userid:"CSTR"} 
] 

我的代碼

Array.from(data).map(x => x.name) 

,但它返回所有的值。

代碼不應該創建任何性能問題,因爲數組將包含500多行。

+1

只是好奇,你知道什麼是角和角度和JavaScript和打字稿之間的區別是什麼? – 2017-10-15 15:13:06

+0

只是好奇。你認爲'Array.from(data)'會做什麼,或者爲什麼它有必要/ – 2017-10-15 15:28:14

回答

-1

您可以使用此一個襯墊,

let newdata = data.reduce((x, y) => x.findIndex(e=>e.name!=y.name)<0 ? [...x, y]: x, []) 

DEMO

var data = [ 
 
      {id:1,name:"sam", userid:"ACD"}, 
 
      {id:1,name:"ram", userid:"SDC"}, 
 
      {id:1,name:"sam", userid:"CSTR"} 
 
]; 
 

 
let newdata = data.reduce((x, y) => x.findIndex(e=>e.name!=y.name)<0 ? [...x, y]: x, []) 
 

 
console.log(newdata);

+0

這隻適用於這個例子。如果您輸入不同的輸入,例如「sam ram dam」或「sam ram ram」,它只會返回第一個對象。 或者,也許我誤解了 –

+0

這個問題,我認爲這是OP需要的!讓我們等到他迴應 – Sajeetharan

+0

爲什麼downvote球員? – Sajeetharan

0

角是一個框架,而不是語言。您的問題中沒有Angular

讓我明白,如果我理解的很好。你有一個對象數組,你想保留所有重複的元素並擺脫其他,好嗎?你可以試試:

data.reduce((acc, value, i, arr) => { 
    if(acc.some(v => v.name === value.name)) return acc; 
    let filtered = arr.filter(v => v.name === value.name); 
    return filtered.length > 1 ? acc.concat(filtered) : acc; 
}, []); 

或者你可以排序的一審陣列,以提高性能:

const sort = (a, b) => a.name.toUpperCase() < b.name.toUpperCase() ? -1 : 1; 

let duplicates = []; 

let sortedArray = data.sort(sort); 

for(let i=0; i<sortedArray.length - 1; i++) { 
    if(sortedArray[i].name === sortedArray[i+1].name) { 
    duplicates.push(sortedArray[i], sortedArray[i+1]); 
    i++; 
    } 
} 
+0

你認爲這個計算複雜度是什麼?鑑於OP關於包含項目丟失的輸入的評論,它將如何執行? – 2017-10-15 15:49:09

+0

複雜度應該是O(n^2),對於大約500個項目它可以。 –

+0

不錯的問題無論如何,我認爲我們可以使用「刪除」關鍵字來降低複雜度,但javascript不喜歡刪除數組項目,因此用戶無法享受性能 –

0

蠻力的方法是過濾陣列只保留這些元素與重複名稱,如過濾器功能duplicateName所示。

// Is there more than one element in an array satisfying some predicate? 
 
const hasMultiple = (arr, pred) => arr.filter(pred).length > 1; 
 

 
// Is this element a duplicate in the context of the array? 
 
const duplicateName = (elt, idx, arr) => hasMultiple(arr, e => e.name === elt.name); 
 

 
// Test data. 
 
var data = [ 
 
    {id:1,name:"sam", userid:"ACD"}, 
 
    {id:1,name:"ram", userid:"SDC"}, 
 
    {id:1,name:"sam", userid:"CSTR"} 
 
]; 
 
    
 
console.log(data.filter(duplicateName));

然而,這將有許多元素的情況下表現不佳(O(n^2))。爲了解決這個問題,你需要預處理數組。我們將爲每個名稱創建一個具有屬性的對象,其值是包含該名稱出現的所有元素的數組。該操作通常稱爲groupBy。一些流行的庫如下劃線將爲您提供這一點。我們會寫我們自己的。分組後,我們將過濾組的對象以刪除只有一個成員的組。

// Group an array by some predicate. 
 
const groupBy = (arr, pred) => arr.reduce((ret, elt) => { 
 
    const val = pred(elt); 
 
    (ret[val] = ret[val] || []).push(elt); 
 
    return ret; 
 
    }, {}); 
 
    
 
// Filter an object, based on a boolean callback. 
 
const filter = (obj, callback) => Object.keys(obj).reduce((res, key) => { 
 
    if (callback(obj[key], key, obj)) res[key] = obj[key]; 
 
    return res; 
 
    }, {}); 
 

 
// Remove groups with only one element. 
 
const removeNonDups = groups => filter(groups, group => group.length > 1); 
 

 
// Test data. 
 
var data = [ 
 
    {id:1,name:"sam", userid:"ACD"}, 
 
    {id:1,name:"ram", userid:"SDC"}, 
 
    {id:1,name:"sam", userid:"CSTR"} 
 
]; 
 

 
console.log(removeNonDups(groupBy(data, elt => elt.name)));

+0

我想過一個類似的方法,但我知道JavaScript使用「delete」關鍵字存在性能泄漏。你知道計算複雜性是否會降低性能泄漏? –

+0

我不知道你可能會談論什麼樣的性能泄漏。請提供參考。 – 2017-10-16 02:15:51

+0

無論如何,我已經刪除了使用'delete'。 – 2017-10-16 02:21:55

相關問題