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

后端 未结 8 2037
逝去的感伤
逝去的感伤 2021-01-14 16:25

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

[
    {
        \"Name\": \"element1\",
        \"Attributes\": [\"1\         


        
相关标签:
8条回答
  • 2021-01-14 17:01

    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
    0 讨论(0)
  • 2021-01-14 17:04
    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)
           }
       });
    })
    
    0 讨论(0)
  • 2021-01-14 17:12

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

    > _.chain(foo).map('Attributes').flatten().uniq().value()
    ["1", "2", "3"]
    
    0 讨论(0)
  • 2021-01-14 17:13

    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), [])
     );

    0 讨论(0)
  • 2021-01-14 17:15

    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)

    0 讨论(0)
  • 2021-01-14 17:16

    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>

    0 讨论(0)
提交回复
热议问题