简体   繁体   English

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

[英]Return unique array values from an array inside an array of objects

I can't find a similar question and I'm a bit stuck.我找不到类似的问题,我有点卡住了。 I have the following JSON array:我有以下 JSON 数组:

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

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

I'm trying to create an array of all the unique elements in the "Attributes" property, but I'm having trouble looping through each object, and then looping through the array elements to return the unique values.我试图在“属性”属性中创建一个包含所有唯一元素的数组,但是我在遍历每个对象,然后遍历数组元素以返回唯一值时遇到问题。 I'm trying to do it with filter(), or map() preferably.我正在尝试使用 filter() 或 map() 来做到这一点。

EDIT: I want an array of unique elements, so: [1,2,3].编辑:我想要一个唯一元素的数组,所以:[1,2,3]。

You could do it with couple of Array methods.你可以用几个 Array 方法来做到这一点。 For example:例如:

 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)

You can use Array#reduce and Array#filter methods您可以使用Array#reduceArray#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 }, []) );


With ES6 arrow function带有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), []) );

If lodash is an option, you can easily get what you want:如果lodash是一个选项,你可以很容易地得到你想要的:

> _.chain(foo).map('Attributes').flatten().uniq().value()
["1", "2", "3"]
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)
       }
   });
})

You have answers to choose from.你有答案可供选择。 Just for fun: this one uses es6只是为了好玩:这个使用 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>

Try This, It'll help to solve this problem.试试这个,它将有助于解决这个问题。

 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>

With ES6/ES2015 you can use Set and the spread operator :在 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);

Explanation (from the inside out):说明(由内而外):

  • input.map(item => item.Attributes) produces an array of the Attributes arrays input.map(item => item.Attributes)产生一个 Attributes 数组
  • [].concat(...) flattens the arrays, ie produces an array of all the Attributes values (including duplicates) [].concat(...)将数组展平,即生成一个包含所有 Attributes 值(包括重复项)的数组
  • new Set() produces a Set from the array, ie stores only the unique Attribute values new Set()从数组中生成一个 Set,即只存储唯一的 Attribute 值
  • [...] produces an array from the Set's values, ie produces an array of all unique Attribute values [...]从 Set 的值生成一个数组,即生成一个包含所有唯一 Attribute 值的数组

Building on top of @dfsq answer, you could replace the two map and reduce with a single flatMap建立在@dfsq 答案之上,您可以用一个flatMap替换两个mapreduce

 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM