繁体   English   中英

Javascript-从数组对象清除重复项

[英]Javascript - clearing duplicates from an array object

嗨,我有一个javascript数组对象,表示在给定国家/地区销售的商品数量,如下所示:

var data = [{'c1':'USA', 'c2':'Item1', 'c3':100}, 
            {'c1':'Canada', 'c2':'Item1', 'c3':120},
            {'c1':'Italy', 'c2':'Item2', 'c3':140},
            {'c1':'Italy', 'c2':'Item2', 'c3':110}]

我需要避免重复(如您所见,最后两个“记录”具有相同的国家/地区和相同的项目),并对金额求和; 如果我从数据库中获取数据,我将使用DISTINCT SUM子句,但是在这种情况下呢? 有什么好的jquery技巧吗?

您可以将一个对象用作不同值的映射,如下所示:

var distincts, index, sum, entry, key;
distincts = {};
sum = 0;
for (index = 0; index < data.length; ++index) {
    entry = data[index];
    key = entry.c1 + "--sep--" + entry.c2;
    if (!distincts[key]) {
        distincts[key] = true;
        sum += entry.c3;
    }
}

工作原理 :JavaScript对象是映射,并且由于对属性的访问是一种极为常见的操作,因此体面的JavaScript实现会设法使属性访问变得非常快(通过在属性键上使用哈希)。 您可以使用方括号( [] )来使用对象名称的字符串访问对象属性,因此obj.fooobj["foo"]都引用objfoo属性。

所以:

  1. 我们从没有属性的对象开始。
  2. 当我们遍历数组时,我们从c1c2创建唯一键。 重要的是“ --sep--”字符串不能出现在c1c2 如果大小写.toLowerCase ,则可以在其中抛出.toLowerCase
  3. 如果distincts已经对该键具有值,那么我们知道我们之前已经看过它,可以忽略它; 否则,我们添加一个值(在这种情况下为true ,但是除了falseundefined0""之外,几乎可以是任何其他0 )作为标志,表明我们之前已经看到过这种独特的组合。 然后将c3加到总和上。

但是正如有人指出的那样,您的最后两个条目实际上并不相同。 我猜这只是问题中的错别字...

jQuery可能为此具有一个数组函数,但是由于您的两个Italy对象不是唯一不同的,因此您需要一个自定义解决方案。 您想填充一个数组,并在进行操作时检查是否有重复:

var data = [{'c1':'USA', 'c2':'Item1', 'c3':100}, 
            {'c1':'Canada', 'c2':'Item1', 'c3':120},
            {'c1':'Italy', 'c2':'Item2', 'c3':140},
            {'c1':'Italy', 'c2':'Item1', 'c3':110}]

var newArray = [];
var dupeCheck = {}; // hash map
for(var i=0; i < data.length; i++){
   if(!dupeCheck[data[i].c1]){
      newArray.push(data[i]);
      dupeCheck[data[i].c1] = true;
   }
}

测试

HTML:

<div id="test"></div>

JS:

var data = [{'c1':'USA', 'c2':'Item1', 'c3':100}, 
            {'c1':'Canada', 'c2':'Item1', 'c3':120},
            {'c1':'Italy', 'c2':'Item2', 'c3':140},
            {'c1':'Italy', 'c2':'Item1', 'c3':110}];

var
 l = data.length, // length
 f = "",          // find
 ix = "",         // index
 d = [];          // delete    

for (var i = 0; i < l; i++) {

   ix = data[i].c1 + "_" + data[i].c2 + "__";

   //var re = new RegExp(ix);

   //if (re.test(f))
   if (f.indexOf(ix) != -1)
     d.push(i);
   else
     f += ix;
}


for (var i1 = 0; i1 < d.length; i1++){

    $("#test").append("<div>for delete: "+d[i1]+"</div>");

}

编辑

尽管chrome的运行速度要快得多,但仅在chrome中使用indexOf的示例才能运行,然后在IE / Opera / Firefox / Safary中对对象的运行速度更快。

“ @ TJ Crowder”创建的代码效率更高。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM