I have an array that returns something like:
const arr = [
{
"id": "5ac2f57f-61cf-454b-9457-484b8484c1d3",
"userID": "7d21e968-f32a-4cb9-a0db-dd98d1d2973a",
"tag": "REPORT_CREATE",
},
{
"id": "3d302f03-75da-40cf-8b86-d9673fdc3b4a",
"userID": "1dafdb46-a49e-4194-9e5b-9c44be7e4cda",
"tag": "REPORT_CREATE",
},
]
And i need to return the frequence of the "userID", but as you can see, it is a subitem.
So if i do something like:
function getOccurrence(array, value) {
var count = 0;
array.forEach((v) => (v === value && count ));
return count;
}
console.log(getOccurrence(arr, "userIDsomething"));
That wouldn't do cause the userID
would have to be the objects itself, not inside [0], [1] and so on. But i am stuck there. Any suggestions?
CodePudding user response:
You just need to compare value
against the userID
property of the items in your array, rather than against the items themselves. Also, it might simplify your code to use filter
.
Try this:
function getOccurrence(array, value) {
return array.filter((v) => v.userID === value).length;
}
CodePudding user response:
You are comparing the value
with the object which will never be equal, You have to compare the value
with its userID
, using v.userID
as
array.forEach((v) => v.userID === value && count );
1) You can use reduce here
arr.reduce((acc, curr) => (curr.userID === value ? acc : acc), 0)
const arr = [
{
id: "5ac2f57f-61cf-454b-9457-484b8484c1d3",
userID: "7d21e968-f32a-4cb9-a0db-dd98d1d2973a",
tag: "REPORT_CREATE",
},
{
id: "3d302f03-75da-40cf-8b86-d9673fdc3b4a",
userID: "1dafdb46-a49e-4194-9e5b-9c44be7e4cda",
tag: "REPORT_CREATE",
},
];
function getOccurrence(array, value) {
return arr.reduce((acc, curr) => (curr.userID === value ? acc : acc), 0);
}
console.log(getOccurrence(arr, "1dafdb46-a49e-4194-9e5b-9c44be7e4cda"));
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
2) You can get occurrences using filter as
arr.filter((o) => o.userID === value).length
const arr = [
{
id: "5ac2f57f-61cf-454b-9457-484b8484c1d3",
userID: "7d21e968-f32a-4cb9-a0db-dd98d1d2973a",
tag: "REPORT_CREATE",
},
{
id: "3d302f03-75da-40cf-8b86-d9673fdc3b4a",
userID: "1dafdb46-a49e-4194-9e5b-9c44be7e4cda",
tag: "REPORT_CREATE",
},
];
function getOccurrence(array, value) {
return arr.filter((o) => o.userID === value).length;
}
console.log(getOccurrence(arr, "1dafdb46-a49e-4194-9e5b-9c44be7e4cda"));
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
As mentioned in the other answers your problem lies in comparing a string value to each iterated object instead of the to the relevant property of the object. To fix it you should simply access the useID
in your comparison.
array.forEach((v) => (v.userID === value && count ));
Other than that your method is fine, and doesn't suffer the side effect of creating a new array as the filter().length
shortcut does.
But hardcoding the userID
into what looks like a utility function doesn't make much sense, so instead you can accept a third property
parameter in your your function to specify the property to compare against. Here using a for...of
instead of forEach()
and checking if the property
is passed and if not just comparing directly.
const arr = [{'id': '5ac2f57f-61cf-454b-9457-484b8484c1d3','userID': '7d21e968-f32a-4cb9-a0db-dd98d1d2973a','tag': 'REPORT_CREATE',},{'id': '3d302f03-75da-40cf-8b86-d9673fdc3b4a','userID': '1dafdb46-a49e-4194-9e5b-9c44be7e4cda','tag': 'REPORT_CREATE',},];
function getOccurrence(array, value, prop) {
let count = 0;
for (const v of array) {
(prop !== undefined ? v[prop] : v) === value && count ;
}
return count;
}
const count = getOccurrence(arr, '1dafdb46-a49e-4194-9e5b-9c44be7e4cda', 'userID');
console.log('1dafdb46-a49e-4194-9e5b-9c44be7e4cda: ', count);
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>