I've got some data like this:
我有一些这样的数据:
const items = [
{ _id: '1', reference: ['abc'] },
{ _id: '2', reference: ['def'] },
{ _id: '3', reference: ['abc'] }
]
The length of items
is always different.
项目的长度总是不同的。
Now I need to get all unique reference strings in a single array. So the result should be
现在我需要在一个数组中获得所有唯一的引用字符串。所以结果应该是
['abc', 'def']
as 'abc'
is a duplicate.
因为abc是一个复制品。
I tried to use a forEach()
loop:
我尝试使用forEach()循环:
const references = []
items.forEach(i => {
references.concat(i.reference)
})
console.log(references)
But references
just gets an empty array result. Also with that I did not take care of duplicates...
但是引用只会得到一个空的数组结果。同时,我也没有处理重复的东西……
I would like to use an ES6 pattern. With that I know I could use something like this:
我想使用ES6模式。有了它,我知道我可以用这样的东西:
const array1 = ['abc']
const array2 = ['def']
const array3 = Array.from(new Set(array1.concat(array2)))
But how can I do this using a loop to get every reference array of each item object - even if I do not know how many objects are in the item array?
但是,如何使用循环来获取每个条目对象的每个引用数组—即使我不知道条目数组中有多少对象?
3 个解决方案
#1
2
If you wanna do a functional style (map-reduce), you can do it like this
如果你想做一个函数样式(map-reduce),你可以这样做
const items = [
{ _id: '1', reference: ['abc'] },
{ _id: '2', reference: ['def'] },
{ _id: '3', reference: ['abc'] }
]
// extract references and put them into a single array
const references =
items
.map(x => x.reference)
.reduce((prev, cur) => prev.concat(cur))
// put them in a set to dedupe
const set = new Set(references)
console.log(references)
console.log([...set])
If you want to do fewer passes over the data, and also avoid the need for Set
you could do.
如果您想减少对数据的传递,并且避免需要设置,您可以这样做。
const items = [
{ _id: '1', reference: ['abc'] },
{ _id: '2', reference: ['def'] },
{ _id: '3', reference: ['abc'] }
]
const result = Object.keys(items.reduce((obj, {reference}) => {
for (const ref of reference) {
obj[ref] = true
}
return obj;
}, {}))
console.log(result)
You can also trade expressiveness for performance with a fully imperative approach below.
您还可以使用下面的一种完全必要的方法来交换表现力和性能。
const items = [
{ _id: '1', reference: ['abc'] },
{ _id: '2', reference: ['def'] },
{ _id: '3', reference: ['abc'] }
];
const occ = {};
const references = [];
for (let i = 0; i < items.length; ++i) {
const refs = items[i].reference;
for (let j = 0; j < refs.length; ++j) {
const ref = refs[j];
if (occ[ref] == null) {
references.push(ref);
occ[ref] = true;
}
}
}
console.log(references)
#2
2
If you want to use Sets, you can use Set.add
, and spread syntax:
如果你想使用集合,你可以使用Set.add和spread语法:
const items = [
{ _id: '1', reference: ['abc'] },
{ _id: '2', reference: ['def'] },
{ _id: '3', reference: ['abc'] }
]
var references = new Set();
items.forEach(i => references.add(...i.reference))
console.log(Array.from(references))
#3
1
This is similar to other solutions here, but creates a reusable function:
这与这里的其他解决方案类似,但创建了一个可重用的功能:
const uniqRefs =
items => [...items.reduce((s, i) => s.add(...i.reference), new Set())]
const items = [{"_id": "1", "reference": ["abc"]}, {"_id": "2", "reference": ["def"]}, {"_id": "3", "reference": ["abc"]}]
console.log(uniqRefs(items))
#1
2
If you wanna do a functional style (map-reduce), you can do it like this
如果你想做一个函数样式(map-reduce),你可以这样做
const items = [
{ _id: '1', reference: ['abc'] },
{ _id: '2', reference: ['def'] },
{ _id: '3', reference: ['abc'] }
]
// extract references and put them into a single array
const references =
items
.map(x => x.reference)
.reduce((prev, cur) => prev.concat(cur))
// put them in a set to dedupe
const set = new Set(references)
console.log(references)
console.log([...set])
If you want to do fewer passes over the data, and also avoid the need for Set
you could do.
如果您想减少对数据的传递,并且避免需要设置,您可以这样做。
const items = [
{ _id: '1', reference: ['abc'] },
{ _id: '2', reference: ['def'] },
{ _id: '3', reference: ['abc'] }
]
const result = Object.keys(items.reduce((obj, {reference}) => {
for (const ref of reference) {
obj[ref] = true
}
return obj;
}, {}))
console.log(result)
You can also trade expressiveness for performance with a fully imperative approach below.
您还可以使用下面的一种完全必要的方法来交换表现力和性能。
const items = [
{ _id: '1', reference: ['abc'] },
{ _id: '2', reference: ['def'] },
{ _id: '3', reference: ['abc'] }
];
const occ = {};
const references = [];
for (let i = 0; i < items.length; ++i) {
const refs = items[i].reference;
for (let j = 0; j < refs.length; ++j) {
const ref = refs[j];
if (occ[ref] == null) {
references.push(ref);
occ[ref] = true;
}
}
}
console.log(references)
#2
2
If you want to use Sets, you can use Set.add
, and spread syntax:
如果你想使用集合,你可以使用Set.add和spread语法:
const items = [
{ _id: '1', reference: ['abc'] },
{ _id: '2', reference: ['def'] },
{ _id: '3', reference: ['abc'] }
]
var references = new Set();
items.forEach(i => references.add(...i.reference))
console.log(Array.from(references))
#3
1
This is similar to other solutions here, but creates a reusable function:
这与这里的其他解决方案类似,但创建了一个可重用的功能:
const uniqRefs =
items => [...items.reduce((s, i) => s.add(...i.reference), new Set())]
const items = [{"_id": "1", "reference": ["abc"]}, {"_id": "2", "reference": ["def"]}, {"_id": "3", "reference": ["abc"]}]
console.log(uniqRefs(items))