【问题标题】:filtering an array for a duplicate value过滤数组中的重复值
【发布时间】:2013-07-01 03:49:55
【问题描述】:

我有一个对象数组,如下所示。第一段代码在一个循环中,其中创建了多个“Item”对象并将其推送到数组中。

此处提供了问题示例:http://jsfiddle.net/X6VML/
请注意更改文本框中的值如何显示重复项。

 // class
 var Item = function(label, value) {
    this.Label = label;
    this.Value = value;
 };

 var obj = new Item("My Label", "My Value");

 // adds object onto array
 itemArray.push(obj);

我遇到的问题是数组可能包含重复的对象,我需要在将对象列表渲染到表中之前将其过滤掉,如下所示:

  for (var i = 0; i < itemArray.length; i++) {
      $('.MyTable').append("<tr><td>" + itemArray[i].Label + "</td><td>" + itemArray[i].Value + "</td></tr>");
  }

我可以确定它是否是重复值,但值相同。如何根据数组中是否已经存在值来过滤对象列表?

非常感谢

【问题讨论】:

    标签: javascript jquery dhtml


    【解决方案1】:

    我有这个方便的实用功能:

    function uniq(ary, key) {
        var seen = {};
        return ary.filter(function(elem) {
            var k = (key || String)(elem);
            return seen[k] === 1 ? 0 : (seen[k] = 1);
        })
    }
    

    其中key 是一个从元素中获取比较键的函数。

    应用于您的用例:

    uniqueItems = uniq(itemArray, function(item) { return item.Value })
    

    【讨论】:

      【解决方案2】:

      一个简单的解决方案是:

      var temp = [];
      $.each(itemArray, function(index, obj){
          var found = false;
          $.each(temp, function(tempI, tempObj){
              if(tempObj.Value == obj.Value){
                  found = true;
                  return false;
              }
          });
      
          if(!found){
              temp.push(obj);
          }
      });
      
      itemArray = temp;
      console.log(itemArray);
      

      上面只是简单地遍历数组中的每个对象,如果它不存在则将其推送到临时数组,最后它用temp覆盖itemArray


      您是否考虑过在添加到数组时消除重复项?像这样的:

      function UniqueItemList(){
          var items = [];
      
          this.push = function(item){
              for(var i=0; i<items.length; i++){
                  if(items[i].Value == item.Value){
                      return;
                  }
              }
              items.push(item);
          };
      
          this.getList = function(){
              return items;
          }
      }
      
      var myList = new UniqueItemList();
      
      myList.push(new Item('label1', 'value1'));
      myList.push(new Item('label2', 'value2'));
      myList.push(new Item('label1', 'value1'));
      myList.push(new Item('label1', 'value1'));
      
      console.log(myList.getList());
      

      如果您尝试推送重复的项目,它将被拒绝。

      Demo - 它已集成到您的代码中。

      【讨论】:

      • 那将是理想的.. 看看你的建议
      • @JamesRadford 查看我的编辑 - 添加了一个集成到您的代码中的演示。 jsfiddle.net/qPSpp/1
      • 谢谢,但是当我更改一个值时,它会复制一个回显值?我需要更新原始项目而不是重复项目。希望这很清楚..?
      • 请看这里,虽然我不确定是否调用 .clear,但我的修改几乎完成了? temp-share.com/show/gFHKQRlzY
      • 当我调用 'clear' 时,列表只显示 1 项.. -- 因为 Clear() 显然删除了它们..
      【解决方案3】:

      只是不要在数组中添加重复项:

      var item = new Item("My Label", "My Value1");
      
      if(!$.grep(itemArray, function(obj) { return obj.Value == item.Value; }).length)
        itemArray.push(item);
      

      如果itemArray中已经有一个值为"My Value1"的对象,就不要添加了。

      【讨论】:

      • 这显然是理想的。我确定这段代码很棒,但你可以重写它,这样我可以看看它在做什么吗?谢谢,
      • 检查文档以获取 $.grep() 方法 api.jquery.com/jQuery.grep。对不起,我不明白你的意思'所以我可以看到它在做什么'???顺便说一句,如果您提供相关代码作为如何在数组中添加新项目,它会更有用。
      【解决方案4】:

      这段代码就可以了。在形成 HTML 之前修改 itemArray。

      var arr = {};
      for ( var i=0; i < itemArray.length; i++ )
          arr[itemArray[i].Value] = itemArray[i];
      itemArray = new Array();
      for ( key in arr )
          itemArray.push(arr[key]);
      

      【讨论】:

      • 实际上认为它非常接近。你能解释一下它在做什么吗?
      • 因为 obj.value 应该是唯一的,所以创建了一个 map,其中 obj.value 作为 key,obj 作为 value。这消除了重复的条目。
      猜你喜欢
      • 2016-12-22
      • 2018-05-08
      • 1970-01-01
      • 2018-11-16
      • 2016-01-08
      • 2021-10-25
      • 1970-01-01
      • 2017-09-08
      • 1970-01-01
      相关资源
      最近更新 更多