如何检查数组在特定对象属性上是否唯一?

时间:2015-05-28 07:15:17

标签: javascript arrays

我有一个对象数组:

var array1 = [
  {
    property1: 10,
    property2: "abc"
  }, 
  {
    property1: 11,
    property2: "def"
  },
  {
    property1: 10,
    property2: "ghi"
  }
];

现在我想要的是根据property1的值,这个数组将被称为不唯一。

这意味着此数组包含2个带property1=10的元素,因此该数组不包含唯一值property1

要检查这一点,我可以使用for循环:

for (var i = 0; i < array1.length; i++) {
  var array2 = array1.slice(); // copy array
  array2.remove(array1[i]);
  var temppropety1 = array1[i].property1;
  for (var j = 0; j < array2.length; j++) {
    if (array2[J].property1==temppropety1) {
      return true;
    }
  }
}

但是有更简单的方法或库可以找到它吗?

6 个答案:

答案 0 :(得分:3)

这是在property1上测试唯一性的简单方法。循环遍历外部数组中的对象,并将每个对象property1添加到临时数组(如果它不在该临时数组中)。如果遇到重复值,则返回false,表示property1不唯一。

function isUnique(arr) {
   var tmpArr = [];
   for(var obj in arr) {
     if(tmpArr.indexOf(arr[obj].property1) < 0){ 
       tmpArr.push(arr[obj].property1);
     } else {
       return false; // Duplicate value for property1 found
     }
   }
   return true; // No duplicate values found for property1
}

演示:http://jsbin.com/lohiqihipe/1/

答案 1 :(得分:0)

我建议数组可能非常大,所以我不想复制它,只是验证属性。

此外,不能使用数组的map函数,因为在这种情况下,你将无法在第一场比赛中打破一个循环:

var equals = function(array) {
    var co = {};
    var unique = true;
    for(var i = 0; i < array.length; i++) {
        var o = array[i];
        if (co[o.property1]) {
            unique = false;
            break;
        } else {
            co[o.property1] = true;
        }
    }
    return unique;
};

答案 2 :(得分:0)

您可以将阵列转换为扁平结构:

array1.map(function(item) { return item.property1; });

现在你的问题简化了检查简单数组中的重复项

var array1 = ["a","b","b","c","d","e","f"];
var uniqueItems = [];
$.each(array1, function(i, el){
    if($.inArray(el, uniqueItems) === -1) uniqueItems.push(el);
});

参考文献:

https://stackoverflow.com/a/840808/4772988

https://stackoverflow.com/a/9229932/4772988

答案 3 :(得分:0)

你可以使用几个助手来抽象它:

var uniqBy = function(f, xs) {
  var seen = []
  return xs.filter(function(x) {
    var fx = f(x)
    if (seen.indexOf(fx) > -1) return
    seen.push(fx)
    return true
  })
}

var dot = function(k) {
  return function(obj) {
    return obj[k]
  }
}

然后通过属性过滤掉重复项,并将结果的长度与原始数组进行比较。如果他们不匹配,那么他们不能是唯一的:

var res = uniqBy(dot('property1'), array1)
var isUnique = array1.length === res.length

console.log(isUnique) // false

如果您只有数字或只有字符串来删除重复项,那么您可以通过使用对象而不是数组来跟踪到目前为止看到的元素来提高性能。

答案 4 :(得分:0)

首先,您可以通过对property1:

的值进行分组来减少(聚合)对象
var grouped = array.reduce(function(grouped, item) {
    var propertyValue = item.property1;
    grouped[propertyValue] = (grouped[propertyValue] || 0) + 1;
    return grouped;
}, {});

然后检查结果对象的每个键的值是否为1:

var result = Object.keys(grouped).every(function(key) {
    return grouped[key] === 1;
});

答案 5 :(得分:0)

您可以使用lodash库来实现此目的。

以下是图书馆文档:https://lodash.com/docs/4.17.5#filter

方法: -

function isDuplicatesPresent(list, propertyName){
   return _.filter(list, function (value) { 
       return _.filter(list, function(innerValue){ reutrn innerValue[propertyName] === value[propertyName]}).length > 1;   
   }).length > 0;
}

实施例: -

var users = [
  { user: 'barney', age: 36, active: true },
  { user: 'fred',  age: 40, active: false },
  { user: 'barney', age: 37, active: true}
];

let duplicates = _.filter(users, function (value) { 
    return _.filter(users, {user:value.user}).length > 1;   
});

结果:

console.log(duplicates)
> [
   {"user": "barney","age": 36,"active": true},
   {"user": "barney","age": 37,"active": true}
 ];