从包含数组的数组中删除重复项

时间:2012-01-09 09:26:04

标签: javascript jquery json

我有像这样的JSON数组

[{"Email":"someone@some.com","Name":"ACO","Groups":["MOD_SW","MOD_PI","MOD_GE"],"Id":63,"Url":"aco"},
{"Email":"someone@some.com","Name":"Agpo","Groups":["MOD_PI"],"Id":22,"Url":"agpo"},
{"Email":"someone@some.com","Name":"Akatherm","Groups":["MOD_SW"],"Id":64,"Url":"akatherm"},
{"Email":"someone@some.com","Name":"Albrand","Groups":["MOD_PI,"MOD_GE"],"Id":23,"Url":"albrand"}]

我想创建一个具有不同Groups的新数组(用于选择标记)。

Groups是一个数组。

我希望selectbox具有以下值:

MOD_SW
MOD_PI
MOD_GE

我的JS:

UpdateSelectMenu: function (selectId, data) {
      $(selectId).empty();
      $(selectId).html("<option value='all' selected='selected'>All groups</option>");
      var array_unique_values = [];

      for (var i = 0; i < data.Groups.length; i++) {
         for (var j = i+1; j < data.Groups.length; j++) {
            if (data.Groups[i] === data.Groups[j]) {
               j = ++i;
            }
         }
         array_unique_values.push(data.Groups[i]);
      }

      array_unique_values = array_unique_values.sort();

      $.each(array_unique_values, function (k, v) {
         $(selectId).append("<option value='" + v + "'>" + v + "</option>");
      });
   }

我也尝试了

for (var i = 0; i < data.length; i++) {  //browse whole data
         for (var j = 0; j < data[i].Groups.length; j++) {  //browse Groups array
            for (var k = j + 1; j < data[i].Groups.length; k++) {
               if (data[i].Groups[j] === data[i].Groups[k]) {
                  continue;
               }
            }

            array_unique_values.push(data[i].Groups[j]);
         }
      }

但错误显示为:Groups.length为空或不是对象

此代码附加select标记组值,但它显示为重复项,因为Groups是一个数组。

我必须创建一个新的for语句来浏览Groups数组吗?

或者还有另一种方法可以避免嵌套for语句吗?

谢谢

2 个答案:

答案 0 :(得分:3)

2个嵌套循环可以完成这项任务:

var data = [... your data ...];
var groups = [];
$.each(data, function(i, item) {
    $.each(item.Groups, function(j, group) {
        if ($.inArray(group, groups) == -1) {
            groups.push(group);
        }
    });    
});

// at this stage groups = ["MOD_SW", "MOD_PI", "MOD_GE"]

如果您想直接在下拉列表中添加选项:

var groups = [];
$.each(data, function(i, item) {
    $.each(item.Groups, function(j, group) {
        if ($.inArray(group, groups) == -1) {
            groups.push(group);
            $(selectId).append(
                $('<option/>', {
                    value: group,
                    text: group
                })
            );
        }
    });    
});

更新:

为了提高效率,您可以定义静态dtstinct方法:

$.extend({
    distinct : function(arr) {
       var result = [];
       $.each(arr, function(index, value) {
           if ($.inArray(value, result) == -1) {
               result.push(value);
           }
       });
       return result;
    }
});

然后使用.map方法:

var data = [... your data ...];
var groups = $.distinct($(data).map(function() {
    return this.Groups;    
}));
$.each(groups, function(index, group) {
    $(selectId).append(
        $('<option/>', {
            value: group,
            text: group
        })
    );
});

答案 1 :(得分:2)

首先看一下最后一组:"Groups":["MOD_PI,MOD_GE"] 你不需要在MOD_PI之后关闭引号并在逗号之后打开它们,或者这是一组组吗?

如果带引号有问题,您的脚本可能如下所示:

var obj = [{"Email":"someone@some.com","Name":"ACO", "Groups":["MOD_SW","MOD_PI","MOD_GE"],"Id":63,"Url":"aco"},
{"Email":"someone@some.com","Name":"Agpo", "Groups":["MOD_PI"],"Id":22,"Url":"agpo"},
{"Email":"someone@some.com","Name":"Akatherm", "Groups":["MOD_SW"],"Id":64,"Url":"akatherm"},
{"Email":"someone@some.com","Name":"Albrand", "Groups":["MOD_PI","MOD_GE"],"Id":23,"Url":"albrand"}]

var temp = {}, 
    result = [];

for (var i = 0; i < obj.length; i+=1) {
    for (var j = 0; j < obj[i]['Groups'].length; j+=1) {
        if (typeof temp[obj[i]['Groups'][j]] === 'undefined') {
            result.push(obj[i]['Groups'][j]);
            temp[obj[i]['Groups'][j]] = true;
        }
    }
}

如果这是一组:

for (var i = 0; i < obj.length; i+=1) {
    for (var j = 0; j < obj[i]['Groups'].length; j+=1) {
        currentGroups = obj[i]['Groups'][j].split(',');
        for (var k = 0; k < currentGroups.length; k += 1) {
            currentGroups[k] = currentGroups[k].replace(/ /g,"");
            if (typeof temp[currentGroups[k]] === 'undefined') {
                result.push(currentGroups[k]);
                temp[currentGroups[k]] = true;
            }       
        }
    }
}

我认为这是最有效的方法,因为您使用O(1)检查重复项,并且您不必执行额外的工作(例如对任何数组进行排序)。