通过检查两个元素从数组中获取重复值

Posted

技术标签:

【中文标题】通过检查两个元素从数组中获取重复值【英文标题】:Get duplicated values from an array by checking with two element 【发布时间】:2018-10-26 01:30:01 【问题描述】:

如果我的数组有以下数据

let array = [ name: "Ramesh", SalseVersion: 10, MarketingCode: 11 ,
         name: "Suresh", SalseVersion: 12, MarketingCode: 13 ,
         name: "Siva", SalseVersion: 10, MarketingCode: 14 ,
         name: "Sakthi", SalseVersion: 10, MarketingCode: 11 ,...]

那么我期待下面的结果

[ name: "Ramesh", SalseVersion: 10, MarketingCode: 11 ,
  name: "Sakthi", SalseVersion: 10, MarketingCode: 11 ]

如果我的数组有以下数据

let array = [ name: "Ramesh", SalseVersion: 10, MarketingCode: 11 ,
         name: "Suresh", SalseVersion: 12, MarketingCode: 14,
         name: "Siva", SalseVersion: 12, MarketingCode: 14 ,
         name: "Sakthi", SalseVersion: 10, MarketingCode: 11 ,...]

那么我期待下面的结果。

        [ name: "Ramesh", SalseVersion: 10, MarketingCode: 11 ,
         name: "Sakthi", SalseVersion: 10, MarketingCode: 11 
         name: "Suresh", SalseVersion: 12, MarketingCode: 14,
         name: "Siva", SalseVersion: 12, MarketingCode: 14 ]

我试过这种方式:Get all non-unique values (i.e.: duplicate/more than one occurrence) in an array

let arr = [ name: "Ramesh", SalseVersion: 10, MarketingCode: 11 ,
         name: "Suresh", SalseVersion: 12, MarketingCode: 13 ,
         name: "Siva", SalseVersion: 10, MarketingCode: 14 ,
         name: "Sakthi", SalseVersion: 10, MarketingCode: 11 ]


var sorted_arr = arr.slice().sort();
var results = [];
for (var i = 0; i < sorted_arr.length - 1; i++) 
    if (sorted_arr[i + 1].SalesVersion == sorted_arr[i].SalesVersion && sorted_arr[i + 1].MarketingCode == sorted_arr[i].MarketingCode) 
        results.push(sorted_arr[i]);
    


console.log(results);

但无法获取重复值。你能解决这个问题吗?

注意:请注意,如果SalseVersionMarketingCode 的值为string/number/Boolean,它应该也可以工作。

因为我尝试了以下一些答案,但我得到了以下错误。

【问题讨论】:

【参考方案1】:

你可以使用reduce

第一个reduce 将使用SalseVersionMarketingCode 的串联值对值进行分组。

第二个reduce 将检查组是否有超过 1 个元素。如果有concat,则将值放入1个数组中。

let array = [ name: "Ramesh", SalseVersion: 10, MarketingCode: 11 , name: "Suresh", SalseVersion: 12, MarketingCode: 14, name: "Siva", SalseVersion: 12, MarketingCode: 14 , name: "Sakthi", SalseVersion: 10, MarketingCode: 11 ];

let result = Object.values(array.reduce((c, v) => 
  let k = v.SalseVersion + '-' + v.MarketingCode;
  c[k] = c[k] || [];
  c[k].push(v);
  return c;
, )).reduce((c, v) => v.length > 1 ? c.concat(v) : c, []);

console.log( result );

【讨论】:

【参考方案2】:

您似乎正在尝试查找在数组中至少存在一个具有相似属性的其他元素的元素。您可以为此使用.filter,然后使用sort

const dupesFromArr = array => 
  const filteredArr = array.filter(( name, SalseVersion, MarketingCode , i, arr) => (
    arr.find((item, findI) => (
      findI !== i &&
      SalseVersion === item.SalseVersion &&
      MarketingCode === item.MarketingCode
    ))
  ));
  return filteredArr.sort((a, b) =>
    String(a.SalseVersion).localeCompare(String(b.SalseVersion), 'kn') ||
    String(a.MarketingCode).localeCompare(String(b.MarketingCode), 'kn')
  );
;

console.log(dupesFromArr([name:"Ramesh",SalseVersion:10,MarketingCode:11,name:"Suresh",SalseVersion:12,MarketingCode:13,name:"Siva",SalseVersion:10,MarketingCode:14,name:"Sakthi",SalseVersion:10,MarketingCode:11]))
console.log(dupesFromArr([name:"Ramesh",SalseVersion:10,MarketingCode:11,name:"Suresh",SalseVersion:12,MarketingCode:14,name:"Siva",SalseVersion:12,MarketingCode:14,name:"Sakthi",SalseVersion:10,MarketingCode:11]))

【讨论】:

我在filteredArr.sort((a, b) =&gt; b.SalesVersion - a.SalesVersion || b.MarketingCode - a.MarketingCode); 中遇到错误赋值的左侧必须是任何int 或枚举变量,因为SalesVersion 属性类型是字符串。 是的,我已经正确复制了它。但是打字稿不允许这样做 您的编辑器告诉您 MarketingCode 属性是 string,但您发布的代码显示它们是整数。这里没有加起来。 @RameshRajendran,您可以使用 + 运算符强制结果。像这样的东西:return filteredArr.sort((a, b) =&gt; +a.SalseVersion - (+b.SalseVersion) || +a.MarketingCode - (+b.MarketingCode)); @Mihai 如果MarketingCodestring,那么+Marketing 将是NaN【参考方案3】:

您可以将您的代码更新为以下

let arr = [ name: "Ramesh", SalseVersion: 10, MarketingCode: 11 ,
     name: "Suresh", SalseVersion: 12, MarketingCode: 14,
     name: "Siva", SalseVersion: 12, MarketingCode: 14 ,
     name: "Sakthi", SalseVersion: 10, MarketingCode: 11 ,
     name: "OP", SalseVersion: 10, MarketingCode: 11 ]

// You need to write the custom sort function
var sorted_arr = arr.slice().sort((a,b) => 
     if(a.SalseVersion === b.SalseVersion) 
          return a.MarketingCode- b.MarketingCode;
      
      return a.SalseVersion - b.SalseVersion;
);
var results = [];
for (var i = 0; i < sorted_arr.length - 1; i++) 
    if (sorted_arr[i + 1].SalesVersion == sorted_arr[i].SalesVersion && sorted_arr[i + 1].MarketingCode == sorted_arr[i].MarketingCode) 
        /* push both the elements in case of match with only exception 
         * being if it has been pushed previously where there are more than 2 matches */
       if (i >= 1 && sorted_arr[i - 1].SalesVersion == sorted_arr[i].SalesVersion && sorted_arr[i - 1].MarketingCode == sorted_arr[i].MarketingCode) 
         results.push(sorted_arr[i+1]);
        else 
         results.push(sorted_arr[i], sorted_arr[i+1]);
                   
    


console.log(results);

【讨论】:

【参考方案4】:

基本上可以继续排序,但是使用想要的键,这会返回一种分组数组,其中所有想要的键及其值都在直接附近。

然后您可以通过检查所有具有实际值的键和前任或后继来过滤数组。

var array = [ name: "Ramesh", SalseVersion: 10, MarketingCode: 11 ,  name: "Suresh", SalseVersion: 12, MarketingCode: 13 ,  name: "Siva", SalseVersion: 10, MarketingCode: 14 ,  name: "Sakthi", SalseVersion: 10, MarketingCode: 11 ],
    keys = ['SalseVersion', 'MarketingCode'],
    result = array
        .sort((a, b) => 
            var d;
            keys.some(k => d = a[k] - b[k]);
            return d;
        )
        .filter((o, i, a) => 
            keys.every(k => a[i - 1] && a[i - 1][k] === o[k]) ||
            keys.every(k => a[i + 1] && o[k] === a[i + 1][k])
        );

console.log(result);
.as-console-wrapper  max-height: 100% !important; top: 0; 

未排序数据的单循环方法,使用哈希表临时收集组的第一个对象或仅指示组的重复项。

var array = [ name: "Ramesh", SalseVersion: 10, MarketingCode: 11 ,  name: "Suresh", SalseVersion: 12, MarketingCode: 13 ,  name: "Siva", SalseVersion: 10, MarketingCode: 14 ,  name: "Sakthi", SalseVersion: 10, MarketingCode: 11 ],
    keys = ['SalseVersion', 'MarketingCode'],
    result = array.reduce((hash => (r, o) => 
        var key = keys.map(k => o[k]).join('|');
        if (key in hash) 
            if (hash[key]) 
                r.push(hash[key]);
                hash[key] = false;
            
            r.push(o);
         else 
             hash[key] = o;
        
        return r;
    )(Object.create(null)), []);

console.log(result);
.as-console-wrapper  max-height: 100% !important; top: 0; 

【讨论】:

以上是关于通过检查两个元素从数组中获取重复值的主要内容,如果未能解决你的问题,请参考以下文章

检查两个数组之间的相等性[重复]

两个数组的最小值[重复]

从两个排序数组中获取前 K 项而不合并它们

php如何删除两个数组中相同的元素

根据具有不同对象的匹配字段从数组列表中删除重复元素

如何从数组中删除重复的数字?