英文:
How to get Unique count based on property value in array of objects
问题
我有一个如下所示的数组:
const array = [
{ _id: '1', userId: '5' },
{ _id: '2', userId: null },
{ _id: '3', userId: null },
{ _id: '4', userId: '1' },
{ _id: '5', userId: '2' },
{ _id: '6', userId: '4' },
{ _id: '7', userId: '4' },
{ _id: '8', userId: null },
{ _id: '9', userId: null },
{ _id: '10', userId: '2' }
];
现在我想获取唯一的 userId 值的计数。如果值为 null,则应分别计数每次出现。如果非 null 的 userId 值多次出现,只应计数一次。
我尝试了下面的函数,但它不考虑 null
值:
const uniqueItems = (list, key) =>
list.reduce(
(resultSet, item) =>
resultSet.add(typeof key === "string" ? item[key] : key(item)),
new Set()
).size;
uniqueItems(array, "userId");
英文:
I have an array as shown below:
const array = [
{ _id: '1', userId: '5' },
{ _id: '2', userId: null },
{ _id: '3', userId: null },
{ _id: '4', userId: '1' },
{ _id: '5', userId: '2' },
{ _id: '6', userId: '4' },
{ _id: '7', userId: '4' },
{ _id: '8', userId: null },
{ _id: '9', userId: null },
{ _id: '10', userId: '2' }
];
Now I want to obtain a count of unique userId values. If a value is null, it should be counted separately for each occurrence. If a non-null userId value appears multiple times, it should only be counted once.
I tried the below function, But it does not consider null
values
const uniqueItems = (list, key) =>
list.reduce(
(resultSet, item) =>
resultSet.add(typeof key === "string" ? item[key] : key(item)),
new Set()
).size;
uniqueItems(array, "userId");
答案1
得分: 3
你可以使用 .reduce()
来将所有元素合并为单个输出。
const array = [
{ _id: '1', userId: '5' },
{ _id: '2', userId: null },
{ _id: '3', userId: null },
{ _id: '4', userId: '1' },
{ _id: '5', userId: '2' },
{ _id: '6', userId: '4' },
{ _id: '7', userId: '4' },
{ _id: '8', userId: null },
{ _id: '9', userId: null },
{ _id: '10', userId: '2' }
];
const {count} = array.reduce((acc, obj) => {
// 如果我们已经有了这个数字,就跳过。
if(acc.cache.includes(obj.userId)) return acc;
// 将新元素添加到缓存中。
if(obj.userId !== null) acc.cache.push(obj.userId);
// 增加计数。
acc.count++;
return acc;
}, {cache: [], count: 0});
console.log(count);
英文:
You can use .reduce()
to combine all elements into a single output.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const array = [
{ _id: '1', userId: '5' },
{ _id: '2', userId: null },
{ _id: '3', userId: null },
{ _id: '4', userId: '1' },
{ _id: '5', userId: '2' },
{ _id: '6', userId: '4' },
{ _id: '7', userId: '4' },
{ _id: '8', userId: null },
{ _id: '9', userId: null },
{ _id: '10', userId: '2' }
];
const {count} = array.reduce((acc, obj) => {
// Skip if we already have the number.
if(acc.cache.includes(obj.userId)) return acc;
// Add new elements to cache.
if(obj.userId !== null) acc.cache.push(obj.userId);
// Increase count.
acc.count++;
return acc;
}, {cache: [], count: 0});
console.log(count);
<!-- end snippet -->
答案2
得分: 0
这可能不是最高效的解决方案,但如果原始数组不是很大,最简单的方法可能是分别计算null
和唯一的非null
元素:
const numNulls = array.filter(x => x.userId === null).length;
const numUniqueNotNull = new Set(array.map(x => x.userId).filter(u => u !== null)).size
const totalSize = numNulls + numUniqueNotNull;
英文:
It may not be the most performant solution, but if the original array isn't huge, the easiest approach may be to separately count null
s and the unique non-null
elements:
const numNulls = array.filter(x => x.userId === null).length;
const numUniqueNotNull = new Set(array.map(x => x.userId).filter(u => u !== null)).size
const totalSize = numNulls + numUniqueNotNull;
答案3
得分: 0
你可以将空值与索引进行映射,以获得唯一标识符。
new Set(array.map((item,index) => (item.userId === null ? `${item.userId}-${index}` : item.userId))).size
英文:
You could map the null value with the index to have a unique identifier.
new Set(array.map((item,index) => (item.userId === null ? `${item.userId}-${index}` : item.userId))).size
答案4
得分: 0
以下是已翻译的代码部分:
const array = [
{ _id: '1', userId: '5' },
{ _id: '2', userId: null },
{ _id: '3', userId: null },
{ _id: '4', userId: '1' },
{ _id: '5', userId: '2' },
{ _id: '6', userId: '4' },
{ _id: '7', userId: '4' },
{ _id: '8', userId: null },
{ _id: '19', userId: null },
{ _id: '10', userId: '2' }
];
const uniqueItems = (list, key) => {
let occurrences = {};
let count = 0;
array.map((item, index) => {
count += typeof item[key] == "string" ? ((occurrences[item[key]]) ? 0 : 1) : 1;
occurrences[item[key]] = 1;
});
return count;
};
console.log(uniqueItems(array, "userId"));
如果您需要进一步的帮助,请随时告诉我。
英文:
const array = [
{ _id: '1', userId: '5' },
{ _id: '2', userId: null },
{ _id: '3', userId: null },
{ _id: '4', userId: '1' },
{ _id: '5', userId: '2' },
{ _id: '6', userId: '4' },
{ _id: '7', userId: '4' },
{ _id: '8', userId: null },
{ _id: '19', userId: null },
{ _id: '10', userId: '2' }
];
const uniqueItems = (list, key) => {
let occurrences = {};
let count = 0;
array.map((item, index) => {
count += typeof item[key] == "string" ? ((occurrences[item[key]]) ? 0 : 1) : 1;
occurrences[item[key]] = 1;
});
return count;
};
console.log(uniqueItems(array, "userId"));
答案5
得分: 0
你可以使用 Array.prototype.reduce() 结合 Set。
代码:
const array = [
{ _id: '1', userId: '5' },
{ _id: '2', userId: null },
{ _id: '3', userId: null },
{ _id: '4', userId: '1' },
{ _id: '5', userId: '2' },
{ _id: '6', userId: '4' },
{ _id: '7', userId: '4' },
{ _id: '8', userId: null },
{ _id: '9', userId: null },
{ _id: '10', userId: '2' },
]
const { users, nulls } = array.reduce(
(a, { userId: id }) => (id ? a.users.add(id) : a.nulls++, a),
{ users: new Set(), nulls: 0 }
)
console.log('Total:', users.size + nulls)
英文:
You can use Array.prototype.reduce() combined with Set
Code:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const array = [
{ _id: '1', userId: '5' },
{ _id: '2', userId: null },
{ _id: '3', userId: null },
{ _id: '4', userId: '1' },
{ _id: '5', userId: '2' },
{ _id: '6', userId: '4' },
{ _id: '7', userId: '4' },
{ _id: '8', userId: null },
{ _id: '9', userId: null },
{ _id: '10', userId: '2' },
]
const { users, nulls } = array.reduce(
(a, { userId: id }) => (id ? a.users.add(id) : a.nulls++, a),
{ users: new Set(), nulls: 0 }
)
console.log('Total:', users.size + nulls)
<!-- end snippet -->
答案6
得分: -1
只需使用 .map
和 .reduce
:
array.map(item => item.userId)
.reduce((prev, cur) => !prev.includes(cur) ? [...prev, cur] : prev, [])
.length
英文:
Just use .map
and .reduce
:
array.map(item => item.userId)
.reduce((prev, cur) => !prev.includes(cur)? [...prev, cur]: prev, [])
.length
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论