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

3

我是一名有用的助手,可以为您进行文本翻译。

以下是需要翻译的内容:

我找不到类似的问题,有点困惑。我有以下JSON数组:

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

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

我正在尝试创建一个数组,其中包含“属性”属性中所有唯一元素,但我在循环每个对象,然后循环遍历数组元素以返回唯一值方面遇到了麻烦。 我想用filter()或map()来实现它。编辑:我希望得到一个唯一元素的数组,例如:[1,2,3]。

请添加所需的结果和您尝试的代码。 - Nina Scholz
我已经添加了所需的输出,但我不知道如何在map()内部执行filter(),并将filter()的输出返回到包含map()的上层。 - DorianHuxley
可能是访问/处理(嵌套)对象、数组或JSON的重复问题。 - Teemu
我没有任何可用的代码...这就是问题所在。 - DorianHuxley
9个回答

2
您可以使用几种数组方法来完成。例如:

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)


不需要使用 applyreturn prev.concat(curr) 就足够了。 - Pranav C Balan

1
你可以使用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
  }, [])
);


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


1
如果lodash是一个选项,你可以轻松地得到你想要的:
> _.chain(foo).map('Attributes').flatten().uniq().value()
["1", "2", "3"]

1
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])

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

0

使用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) 生成一个 Attributes 数组的数组
  • [].concat(...) 将数组扁平化,即生成包含所有 Attributes 值的数组(包括重复值)
  • new Set() 从数组中生成一个 Set,即仅存储唯一的 Attribute 值
  • [...] 从 Set 的值生成一个数组,即生成所有唯一 Attribute 值的数组

0

你有可供选择的答案。只是为了好玩:这个使用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

试试这个,它会帮助解决这个问题。

  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>


0
在 @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)


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接