从对象数组中的数组返回唯一的数组值

Return unique array values from an array inside an array of objects

本文关键字:数组 唯一 返回 对象      更新时间:2023-09-26

我找不到类似的问题,我有点卡住了。我有以下JSON数组:

[
    {
        "Name": "element1",
        "Attributes": ["1", "2"]
    },
    {
        "Name": "element2",
        "Attributes": ["1","3" ]
    },
    {
        "Name": "element3",
        "Attributes": []
    }
]

我试图在"Attributes"属性中创建一个包含所有唯一元素的数组,但是我在循环每个对象时遇到了麻烦,然后循环数组元素以返回唯一值。我试着用filter(),或者map()来做。

编辑:我想要一个唯一元素的数组,所以:[1,2,3].

你可以用几个Array方法来做。例如:

var result = [
    {
        "Name": "element1",
        "Attributes": ["1", "2"]
    },
    {
        "Name": "element2",
        "Attributes": ["1","3" ]
    },
    {
        "Name": "element3",
        "Attributes": []
    }
]
// map to [ ["1", "2"], ["1", "3"], [] ]
.map(item => item.Attributes)
// flatten to [ "1", "2", "1", "3" ]
.reduce((prev, curr) => prev.concat(curr), [])
// filter unique [ "1", "2", "3" ]
.filter((item, i, arr) => arr.indexOf(item) === i)
console.log(result)

如果lodash是一个选项,您可以很容易地得到您想要的:

> _.chain(foo).map('Attributes').flatten().uniq().value()
["1", "2", "3"]

可以使用 Array#reduce Array#filter 方法

var data = [{
    "Name": "element1",
    "Attributes": ["1", "2"]
  },
  {
    "Name": "element2",
    "Attributes": ["1", "3"]
  }, {
    "Name": "element3",
    "Attributes": []
  }
]
console.log(
  // iterate over array elements
  data.reduce(function(arr, ele) {
    // push the unique values to array
    [].push.apply(arr,
      // filter out unique value
      ele.Attributes.filter(function(v) {
        // check element present in array
        return arr.indexOf(v) == -1;
      })
    );
    // return the unique array
    return arr;
    // set initial argument as an empty array
  }, [])
);


带有ES6箭头功能

 var data = [{
     "Name": "element1",
     "Attributes": ["1", "2"]
   },
   {
     "Name": "element2",
     "Attributes": ["1", "3"]
   }, {
     "Name": "element3",
     "Attributes": []
   }
 ]
 console.log(
   data.reduce((arr, ele) => ([].push.apply(arr, ele.Attributes.filter((v) => arr.indexOf(v) == -1)), arr), [])
 );

let uniqueSet = new Set()
let a = [
    {
        "Name": "element1",
        "Attributes": ["1", "2"]
    },
    {
        "Name": "element2",
        "Attributes": ["1","3" ]
    },
    {
        "Name": "element3",
        "Attributes": []
    }
]
for(let i=0; i<a.length; i++){
    a[i].Attributes.map((x) => uniqueSet.add(x))
}
console.log([...uniqueSet])
var uniqueArr = [];
var arr = [
    {
        "Name": "element1",
        "Attributes": ["1", "2"]
    },
    {
        "Name": "element2",
        "Attributes": ["1","3" ]
    },
    {
        "Name": "element3",
        "Attributes": []
    }
];
arr.forEach(function(obj) {
   var attr = obj.Attributes;
   attr.forEach(function(val){
       if (uniqueArray.indexOf(val) < 0) {
           uniqueArray.push(val)
       }
   });
})

你可以从中选择答案。只是为了好玩:这个使用了es6

"use strict";
let uniqueAttr = [];
const obj = [
    {
        "Name": "element1",
        "Attributes": ["1", "2"]
    },
    {
        "Name": "element2",
        "Attributes": ["1","3" ]
    },
    {
        "Name": "element3",
        "Attributes": []
    }
];
obj.forEach( element => 
  element.Attributes.forEach( 
    attr => uniqueAttr.indexOf(attr) < 0  && uniqueAttr.push(attr)
  ) 
);
document.querySelector("#result").textContent = uniqueAttr;
<pre id="result"></pre>

试试这个,它将有助于解决这个问题。

  var data = [{
    "Name": "element1",
    "Attributes": ["1", "2"]
  }, {
    "Name": "element2",
    "Attributes": ["1", "3"]
  }, {
    "Name": "element3",
    "Attributes": []
  }];
  var Attributes = [];
  $.each(data, function(i, e) {
    $.each(e.Attributes, function(i, e) {
      Attributes.push(parseInt(e));
    });
  });
  Attributes = $.unique(Attributes);
  alert(Attributes);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

对于ES6/ES2015,您可以使用Set和扩展操作符:

const input = [
    {
        "Name": "element1",
        "Attributes": ["1", "2"]
    },
    {
        "Name": "element2",
        "Attributes": ["1","3" ]
    },
    {
        "Name": "element3",
        "Attributes": []
    }
];
const output = [...new Set([].concat(...input.map(item => item.Attributes)))];
console.log(output);

说明(由内而外):

  • input.map(item => item.Attributes)生成一个属性数组
  • [].concat(...)扁平化数组,即产生所有属性值的数组(包括重复的)
  • new Set()从数组中产生一个Set,即只存储唯一的属性值
  • [...]从Set的值生成一个数组,即生成一个包含所有唯一属性值的数组

在@dfsq答案的基础上,您可以将两个mapreduce替换为单个flatMap

var result = [
    {
        "Name": "element1",
        "Attributes": ["1", "2"]
    },
    {
        "Name": "element2",
        "Attributes": ["1","3" ]
    },
    {
        "Name": "element3",
        "Attributes": []
    }
]
// map & flatten to [ "1", "2", "1", "3" ]
.flatMap(item => item.Attributes)
// filter unique [ "1", "2", "3" ]
.filter((item, i, arr) => arr.indexOf(item) === i)
console.log(result)