admin管理员组

文章数量:1331923

I can't find a similar question and I'm a bit stuck. I have the following JSON array:

[
    {
        "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.

EDIT: I want an array of unique elements, so: [1,2,3].

I can't find a similar question and I'm a bit stuck. I have the following JSON array:

[
    {
        "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.

EDIT: I want an array of unique elements, so: [1,2,3].

Share Improve this question edited Jul 2, 2016 at 9:51 Pranav C Balan 115k25 gold badges171 silver badges195 bronze badges asked Jul 2, 2016 at 9:37 DorianHuxleyDorianHuxley 6624 gold badges10 silver badges22 bronze badges 4
  • please add the wanted result and the code you tried. – Nina Scholz Commented Jul 2, 2016 at 9:38
  • I'vr added my desired output, but I'm stuck with how to do a filter() within a map(), and return the output of the inside filter() back up the the containing map() – DorianHuxley Commented Jul 2, 2016 at 9:40
  • Possible duplicate of Access / process (nested) objects, arrays or JSON – Teemu Commented Jul 2, 2016 at 9:41
  • I don't have any working code.. that's the problem. – DorianHuxley Commented Jul 2, 2016 at 9:42
Add a ment  | 

9 Answers 9

Reset to default 2

You could do it with couple of Array methods. 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)

If lodash is an option, you can easily get what you want:

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

You can use Array#reduce and Array#filter methods

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

 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)
       }
   });
})

You have answers to choose from. Just for fun: this one uses 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./ajax/libs/jquery/1.9.1/jquery.min.js"></script>

With ES6/ES2015 you can use Set and the spread operator:

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
  • [].concat(...) flattens the arrays, i.e. produces an array of all the Attributes values (including duplicates)
  • new Set() produces a Set from the array, i.e. stores only the unique Attribute values
  • [...] produces an array from the Set's values, i.e. produces an array of all unique Attribute values

Building on top of @dfsq answer, you could replace the two map and reduce with a single 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)

本文标签: javascriptReturn unique array values from an array inside an array of objectsStack Overflow