根据对象数组中的属性值获取唯一计数的方法

huangapple go评论72阅读模式
英文:

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: &#39;1&#39;, userId: &#39;5&#39; },
  { _id: &#39;2&#39;, userId: null },
  { _id: &#39;3&#39;, userId: null },
  { _id: &#39;4&#39;, userId: &#39;1&#39; },
  { _id: &#39;5&#39;, userId: &#39;2&#39; },
  { _id: &#39;6&#39;, userId: &#39;4&#39; },
  { _id: &#39;7&#39;, userId: &#39;4&#39; },
  { _id: &#39;8&#39;, userId: null },
  { _id: &#39;9&#39;, userId: null },
  { _id: &#39;10&#39;, userId: &#39;2&#39; }
];

const {count} = array.reduce((acc, obj) =&gt; {
  // 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 nulls and the unique non-null elements:

const numNulls = array.filter(x =&gt; x.userId === null).length;
const numUniqueNotNull = new Set(array.map(x =&gt; x.userId).filter(u =&gt; 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) =&gt; (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: &#39;1&#39;, userId: &#39;5&#39; },
  { _id: &#39;2&#39;, userId: null },
  { _id: &#39;3&#39;, userId: null },
  { _id: &#39;4&#39;, userId: &#39;1&#39; },
  { _id: &#39;5&#39;, userId: &#39;2&#39; },
  { _id: &#39;6&#39;, userId: &#39;4&#39; },
  { _id: &#39;7&#39;, userId: &#39;4&#39; },
  { _id: &#39;8&#39;, userId: null },
  { _id: &#39;19&#39;, userId: null },
  { _id: &#39;10&#39;, userId: &#39;2&#39; }
];

const uniqueItems = (list, key) =&gt; {
  let occurrences = {}; 
  let count = 0;
  array.map((item, index) =&gt; {
    count += typeof item[key] == &quot;string&quot; ? ((occurrences[item[key]]) ? 0 : 1) : 1;
    occurrences[item[key]] = 1;
  });
  return count;
};

console.log(uniqueItems(array, &quot;userId&quot;));

答案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: &#39;1&#39;, userId: &#39;5&#39; },
  { _id: &#39;2&#39;, userId: null },
  { _id: &#39;3&#39;, userId: null },
  { _id: &#39;4&#39;, userId: &#39;1&#39; },
  { _id: &#39;5&#39;, userId: &#39;2&#39; },
  { _id: &#39;6&#39;, userId: &#39;4&#39; },
  { _id: &#39;7&#39;, userId: &#39;4&#39; },
  { _id: &#39;8&#39;, userId: null },
  { _id: &#39;9&#39;, userId: null },
  { _id: &#39;10&#39;, userId: &#39;2&#39; },
]

const { users, nulls } = array.reduce(
  (a, { userId: id }) =&gt; (id ? a.users.add(id) : a.nulls++, a),
  { users: new Set(), nulls: 0 }
)

console.log(&#39;Total:&#39;, 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 =&gt; item.userId)
  .reduce((prev, cur) =&gt; !prev.includes(cur)? [...prev, cur]: prev, [])
  .length

huangapple
  • 本文由 发表于 2023年6月8日 21:20:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76432283.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定