在对象数组中查找重复的设置值

时间:2018-09-11 13:27:49

标签: javascript arrays angularjs

我有一个带有HTML表的UI,我们可以在其中添加动态行和列(angularjs)

该表具有2个静态列ID和描述,其余列是动态列,用户必须在其中添加一个或多个列。(单击按钮) 单击“保存”按钮,我要验证用户是否添加了唯一的动态列。

下面的变量保存行的数组,如下所示:

 $scope.myTable.Rows 

下面是用户仅添加一个动态列和2行时生成的数组。 id&description是静态列,而“ 0”是添加的动态列。

{0: "1111", description: "desc1", id: "1111"}
{0: "2222", description: "desc2", id: "2222"}

另一个示例,其中添加了3个动态列,3行:

{0: "a1", 1: "a2", 2: "a3", description: "desc1", id: "1111"}
{0: "a5", 1: "a6", 2: "a7", description: "desc2", id: "2222"}
{0: "a9", 1: "a10", 2: "a11", description: "desc3", id: "3333"}

我想检查上述数组是否仅在动态列组合的情况下是唯一的。也就是说,按照上述动态列0,1,2的数组设置值,不应在数组的任何其他行中重复。

因此下面的数组集不应通过验证:

{0: "a1", 1: "a2", 2: "a3", description: "desc1", id: "1111"}
{0: "a5", 1: "a6", 2: "a7", description: "desc2", id: "2222"}
{0: "a1", 1: "a2", 2: "a3", description: "desc3", id: "3333"}

如您所见,上面的第三行类似于第一行。我不想考虑“ id”和“ description”列

以下内容仍然是唯一的:

{0: "a1", 1: "a2", 2: "a3", description: "desc1", id: "1111"}
{0: "a5", 1: "a6", 2: "a7", description: "desc2", id: "2222"}
{0: "a1", 1: "a2", 2: "a9", description: "desc3", id: "3333"}

我尝试在以下位置查看几篇文章: How can I check if the array of objects have duplicate property values?

但是大多数原因是查看单个属性,看看是否存在重复项,而不是合并的集合。

我希望我已明确说明了我的要求。让我知道您是否需要更多信息。

-更新-

我尝试使用as

 let array = [
  {0: "a1", 1: "a2", 2: "a3", description: "desc1", id: "1111"},
 {0: "a5", 1: "a6", 2: "a7", description: "desc2", id: "2222"},
 {0: "a1", 1: "a2", 2: "a3", description: "desc3", id: "3333"}];

 let jsonRows = JSON.parse(JSON.stringify(array));
 var valueArr = jsonRows.map(function(item){ return item."0" });
   //above gives error: Uncaught SyntaxError: Unexpected string
 var isDuplicate = valueArr.some(function(item, idx){ 
return valueArr.indexOf(item) != idx 
 });

console.log(jsonRows);

3 个答案:

答案 0 :(得分:1)

这是我想我们可以在这里做的非常简单的事情,用键作为每行每个动态属性的值创建一个映射。如果已找到某个属性,则将每一行添加到地图上,并找到重复项。

我已经使用||作为分隔符将每个值组合在一起以形成唯一键,并使用一个不会成为动态属性值的唯一键。

 function isUniqueData(data) {
    let map = {}, isUnique = true;
    data.filter(function(item, index) {
      let prop = "";
      for(var key in item) {
        if(key != "description" && key != "id") {
          prop += item[key] + "||";
        }  
      }
      if(map[prop]) {
        isUnique = false;
      } else {
        map[prop] = item;
      }
    }); 
    return isUnique;
 }

var data1 = [
  {0: "a1", 1: "a2", 2: "a3", description: "desc1", id: "1111"},
  {0: "a5", 1: "a6", 2: "a7", description: "desc2", id: "2222"},
  {0: "a5", 1: "a6", 2: "a7", description: "desc2", id: "2222"},
  {0: "a1", 1: "a2", 2: "a9", description: "desc3", id: "3333"}
];
console.log(isUniqueData(data1))

var data2 = [
  {0: "a1", 1: "a2", description: "desc1", id: "1111"},
  {0: "a5", 1: "a6", description: "desc2", id: "2222"},
  {0: "a1", 1: "a4", description: "desc3", id: "3333"}
];
console.log(isUniqueData(data2))

答案 1 :(得分:1)

释义您的问题:

  

给定多个键,如何查找键:值对多次出现的数组中的所有行?

我使用了以下行:

var rows = [
  {0: 'a1', 1: 'a2', 2: 'a3', description: 'desc1', id: '1111'},
  {0: 'a5', 1: 'a6', 2: 'a7', description: 'desc2', id: '2222'},
  {0: 'a1', 1: 'a2', 2: 'a3', description: 'desc3', id: '3333'}
];

我的回答可能有点冗长:

  1. 将数组递归地移到我要唯一的键的单独列表上。
  2. 对于每个给定的键,找到该键的每个值的出现次数。
  3. 如果该值的计数为> 1,则将该行推入重复项数组

您可以使用Lodash中的#countBy之类的函数来缩短解决方案。

function duplicates(arr, keys = []) {
  if (keys.length) {
    const key = keys[0];
    const keyValueCounts = count(arr.map(row => row[key]));

    return duplicates(
      arr.reduce((acc, row) => {
        if (keyValueCounts[row[key]] > 1) {
          return acc.concat(row);
        } else {
          return acc;
        }
      }, []),
      keys.slice(1)
    );
  } else {
    return arr;
  }
}

/// or _.countsBy(arr);
function count(arr) {
  const counts = {};

  arr.forEach(value => {
    counts[value] = Number.isInteger(counts[value])
      ? counts[value] + 1
      : 1;
  });

  return counts;
}

console.log(duplicates(rows, [0, 1, 2]));

答案 2 :(得分:0)

您可以编写一个查看所有元素的函数,直到找到两个具有相同$target = "img/".basename(explode('.',$image)[0] . date('m-d-Y_hia') . explode('.',$image)[1]); 01属性的元素为止:

2