2017-10-15 99 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