Loop through array of object and get values - javascript

I have below object and i need counts from the byPerson array inside the object. Basically, i want to check the count in each byPerson array elements and get those properties as an array.
for e.g.
var Closed = [16, 0, 1, 43] // here 1st count object has 16 as closed, 2nd count object has no closed property (so we set it to 0), 3rd one has value 1 and 4th one has value 43
Similarly
var Verify = [0, 5, 0, 1]
How can i achieve this calculation and stored the results in Closed and Verify variables as shown above.
{
"byPerson": [
{
"personId": "1514903899",
"firstName": "Yatish",
"lastName": "Patel",
"count": {
"Closed": 16,
}
},
{
"personId": "1559363884",
"firstName": "Samuel",
"lastName": "Chacko",
"count": {
"Verify": 5
}
},
{
"personId": "297895805",
"firstName": "Tim",
"lastName": "Altman",
"count": {
"Closed": 1
}
},
{
"personId": "others",
"firstName": "Others",
"lastName": "",
"count": {
"Closed": 43,
"Verify": 1
}
}
],
"resultDateTime": "2021-04-23T12:14:33.901"
}
I tried this way
const closedValues= releaseData.byPerson.map(element => element.count["Closed"] === undefined ? 0: element.count["Closed"]);
const verifyValues= releaseData.byPerson.map(element => element.count["Verify"] === undefined ? 0: element.count["Verify"]);
```
But i guess it is not the optimal solution where i have to calculate for each one seperately.

You can use Array.reduce to count this in one go:
const data = {
"byPerson": [{
"personId": "1514903899",
"firstName": "Yatish",
"lastName": "Patel",
"count": {
"Closed": 16,
}
},
{
"personId": "1559363884",
"firstName": "Samuel",
"lastName": "Chacko",
"count": {
"Verify": 5
}
},
{
"personId": "297895805",
"firstName": "Tim",
"lastName": "Altman",
"count": {
"Closed": 1
}
},
{
"personId": "others",
"firstName": "Others",
"lastName": "",
"count": {
"Closed": 43,
"Verify": 1
}
}
],
"resultDateTime": "2021-04-23T12:14:33.901"
}
const result = data.byPerson.reduce((result, {
count
}) => {
result.closed.push(count.Closed || 0);
result.verify.push(count.Verify || 0);
return result;
}, {
closed: [],
verify: []
});
console.log(result);

Related

Assigning a grouped index within a javascript array

How would I assign an index to each object within a group in an array using javascript. So starting at zero and counting up inside each group, ordered by the group then the id.
Starting with this
let data = [
{ "id": "AB", "name": "Fred", "group": 1},
{ "id": "BC", "name": "Jane", "group": 2 },
{ "id": "CD", "name": "Mary", "group": 1 },
{ "id": "DE", "name": "Bob", "group": 2 },
{ "id": "EF", "name": "Chris", "group": 1 },
{ "id": "FG", "name": "Steve", "group": 2 },
{ "id": "GH", "name": "Jim", "group": 2 }
]
But adding the groupIndex field for each object.
dataGrouped = [
{ "id": "DE", "name": "Bob", "group": 2, "groupIndex": 1 },
{ "id": "EF", "name": "Chris", "group": 1, "groupIndex": 2 },
{ "id": "BC", "name": "Jane", "group": 2, "groupIndex": 0 },
{ "id": "FG", "name": "Steve", "group": 2, "groupIndex": 2 },
{ "id": "AB", "name": "Fred", "group": 1, "groupIndex": 0},
{ "id": "CD", "name": "Mary", "group": 1, "groupIndex": 1 },
{ "id": "GH", "name": "Jim", "group": 2, "groupIndex": 3 }
]
You could take an object for the indices.
const
indices = {},
data = [{ id: "AB", name: "Fred", group: 1 }, { id: "BC", name: "Jane", group: 2 }, { id: "CD", name: "Mary", group: 1 }, { id: "DE", name: "Bob", group: 2 }, { id: "EF", name: "Chris", group: 1 }, { id: "FG", name: "Steve", group: 2 }, { id: "GH", name: "Jim", group: 2 }],
result = data.map(o => {
indices[o.group] ??= 0;
return { ...o, groupIndex: indices[o.group]++ };
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Presented below is one possible way to achieve the desired objective (viz, assigning group index to array elements). This solution does not address: "ordered by the group then the id."
Code Snippet
// method to assign group-index
// the resulting array may get ordered based on group & group-index (ascending)
const assignGroupIndex = arr => (
Object.values(
arr?.reduce(
(acc, { group, ...rest }) => {
if (!(group in acc)) acc[group] = [];
acc[group].push({
group, ...rest, groupIndex: acc[group].length,
});
return acc;
},
{}
)
).flat()
);
/*
// method to assign group-index for each elt in array
const assignGroupIndex = arr => ( // arg "arr" is the input array
// extract the values from the intermediate result object generated below
Object.values(
// use ".reduce()" to iterate the array and generate an intermediate result
arr?.reduce(
// "acc" is the accumulator, destructure to access "group" & other props
(acc, { group, ...rest }) => {
// if "group" not already in accumulator, set the value as empty array
if (!(group in acc)) acc[group] = [];
// push to the array a new object with "groupIndex" as current length
acc[group].push({
group, ...rest, groupIndex: acc[group].length,
});
// always return the accumulator for each iteration of ".reduce()"
return acc;
},
{} // "acc" - the accumulator is initialized as empty object
)
).flat() // use ".flat()" to remove nested arrays from Object.values()
);
*/
let data = [
{ "id": "AB", "name": "Fred", "group": 1},
{ "id": "BC", "name": "Jane", "group": 2 },
{ "id": "CD", "name": "Mary", "group": 1 },
{ "id": "DE", "name": "Bob", "group": 2 },
{ "id": "EF", "name": "Chris", "group": 1 },
{ "id": "FG", "name": "Steve", "group": 2 },
{ "id": "GH", "name": "Jim", "group": 2 }
];
console.log(
'assigned group-index to array:\n',
assignGroupIndex(data)
);
.as-console-wrapper { max-height: 100% !important; top: 0 }
Explanation
Inline comments added to the snippet above.
let data = [
{ "id": "AB", "name": "Fred", "group": 1},
{ "id": "BC", "name": "Jane", "group": 2 },
{ "id": "CD", "name": "Mary", "group": 1 },
{ "id": "DE", "name": "Bob", "group": 2 },
{ "id": "EF", "name": "Chris", "group": 1 },
{ "id": "FG", "name": "Steve", "group": 2 },
{ "id": "GH", "name": "Jim", "group": 2 }
];
let groupCounts = {};
let dataGrouped = data.map(i=>({
...i,
groupIndex: groupCounts[i.group] = ++groupCounts[i.group] || 0
})).sort((a,b)=>a.group-b.group || a.id.localeCompare(b.id));
console.log(dataGrouped);

Object with nested array to filter, want to return entire object with new filtered array

I'm attempting to remove an object out of an array nested within my movie object and then copy it to a new variable. So my original object looks like this:
{
"id": 1,
"title": "Avatar",
"movieLength": 162,
"releaseDate": "2009-12-18",
"trailerUrl": "https://www.youtube.com/watch?v=5PSNL1qE6VY",
"genre": {
"id": 1,
"genre": "Action"
},
"rating": {
"id": 3,
"rating": "PG-13"
},
"director": {
"id": 1,
"lastName": "Cameron",
"firstName": "James"
},
"actors": [
{
"id": 2,
"lastName": "Worthington",
"firstName": "Sam"
},
{
"id": 3,
"lastName": "Weaver",
"firstName": "Sigourney"
},
{
"id": 4,
"lastName": "Saldana",
"firstName": "Zoe"
}
],
"comments": []
}
and what I'm doing right now is
const updatedMovie = const updatedMovie = movie.actors.filter((actor) => actor.id !== id);
but as you know that only returns the array of actors I filtered. I want to copy the entire object with the newly filtered actors so the object will come out like this (removing actor id 3):
{
"id": 1,
"title": "Avatar",
"movieLength": 162,
"releaseDate": "2009-12-18",
"trailerUrl": "https://www.youtube.com/watch?v=5PSNL1qE6VY",
"genre": {
"id": 1,
"genre": "Action"
},
"rating": {
"id": 3,
"rating": "PG-13"
},
"director": {
"id": 1,
"lastName": "Cameron",
"firstName": "James"
},
"actors": [
{
"id": 2,
"lastName": "Worthington",
"firstName": "Sam"
},
{
"id": 4,
"lastName": "Saldana",
"firstName": "Zoe"
}
],
"comments": []
}
I've tried reading around but I'm not having any luck getting any solutions to work with me, so if anyone can help or point me in the right direction that would be great!
If you want to mutate the existing object, just assign the result of the .filter to the .actors property.
movie.actors = movie.actors.filter((actor) => actor.id !== id);
console.log(movie);
If you want to keep the existing object unmutated, spread the rest of the properties into a new object while filtering.
const updatedMovie = {
...movie,
actors: movie.actors.filter((actor) => actor.id !== id)
};
console.log(updatedMovie);
const movies = {
"id": 1,
"title": "Avatar",
"movieLength": 162,
"releaseDate": "2009-12-18",
"trailerUrl": "https://www.youtube.com/watch?v=5PSNL1qE6VY",
"genre": {
"id": 1,
"genre": "Action"
},
"rating": {
"id": 3,
"rating": "PG-13"
},
"director": {
"id": 1,
"lastName": "Cameron",
"firstName": "James"
},
"actors": [
{
"id": 2,
"lastName": "Worthington",
"firstName": "Sam"
},
{
"id": 3,
"lastName": "Weaver",
"firstName": "Sigourney"
},
{
"id": 4,
"lastName": "Saldana",
"firstName": "Zoe"
}
],
"comments": []
}
const id = 3; // or any other id you want
const actors = movies.actors.filter(actor => actor.id != id)
const newMovies = Object.assign({}, movies , { actors })
console.log(newMovies)

copying an array of object and ordering some items

I have an array of object and I want to copy that array of object to another array while modifying some items, like copying id only by ascending order and copying only the value of trophies of basketball to trophies. How to do it?
const item = [{
"id": 33,
"name": "John"
"trophies": {
"basketball" : 2,
"baseball" : 5
},
"profile": "profile/212"
}
{
"id": 12,
"name": "Michael"
"trophies": {
"basketball" : 6,
"baseball" : 7
},
"profile": "profile/341"
}
]
I want the above array of object after copying to look something like
const item2 = [{
"id": 12,
"name": "Michael"
"trophies": 6,
"profile": "http://collegeprofile.com/profile/341"
},
{
"id": 33,
"name": "John"
"trophies": 2,
"profile": "http://collegeprofile.com/profile/212"
}
]
You can sort by id ascending order using Array.prototype.sort
And map basketball value to trophies using Array.prototype.map.
const item = [{
"id": 33,
"name": "John",
"trophies": {
"basketball": 2,
"baseball": 5
},
"profile": "profile/212"
}, {
"id": 12,
"name": "Michael",
"trophies": {
"basketball": 6,
"baseball": 7
},
"profile": "profile/341"
}];
const output = item.sort((a, b) => (a.id - b.id)).map((item) => ({
...item,
trophies: item.trophies.basketball,
profile: "http://collegeprofile.com/" + item.profile
}));
console.log(output);

Object not replacing using spread operator

I want to replace existing object with new updated fields using spread operator. But I am not getting the correct result.
Below are my two objects.
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
I can do it with .map. Below is my code.
let result = obj1.map(item => {
if (item.id === newObj.id) {
return {...item, ...newObj};
}
return item;
});
But I do not want to run the loop and want to acheive by spread operator only.
Example for spread. Which is not working. It's not replacing the object. Instead creating one more.
[...obj1, newObj];
Can someone help me?
JSBIN CODE SNIPPET
Spread syntax doesn't replace the object within array like you used it. Using map is the simplest and understandable way. However if you want to use spread syntax you would first need to find the index to be replaced and then use slice on array
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
const idx = obj1.findIndex(item => item.id === newObj.id);
obj1 = [...obj1.slice(0, idx), newObj, ...obj1.slice(idx + 1)];
console.log(obj1);
Use Object.assign
The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
Object.assign(obj1[2], newObj);
console.log(obj1)
Using .find() to get the target obj
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
const targetObj = obj1.find(obj => obj.id === newObj.id)
Object.assign(targetObj, newObj);
console.log(obj1)
you should normalize your data by id this way:
obj1 = {
1: {
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
2: {
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
3: {
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
}
newObj = {
3: {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
}
this way you can use spread operator:
{ ...obj1, ...newObj }
in order to normalize you can use the reduce func this way:
const normalized = obj1.reduce((result, obj) => ({ ...result, [obj.id]: obj }), {})
Spread operator is magic but it won't do whatever you want, you will have to loop over and replace the object. Instead of doing a map(), I would prefer find(). The use Object.assign() to achieve what you want.
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
let foundOb = obj1.find(e => e.id === newObj.id);
Object.assign(foundOb, newObj)
console.log(obj1)
You cannot use spread syntax in that way. One solution would be to find index of the object you want to replace by id property and then you could use spread syntax with slice method to create new array with replaced object.
let obj1 = [{"id":1,"name":"Michel","age":34,"email":"michel#gmail.com"},{"id":2,"name":"Abby","age":40,"email":"abby#gmail.com"},{"id":3,"name":"Gary","age":40,"email":"abby#gmail.com"}]
let newObj = {"id":3,"name":"Gary","age":23,"email":"gary#gmail.com"}
const index = obj1.findIndex(({id}) => id == newObj.id)
const result = [...obj1.slice(0, index), newObj, ...obj1.slice(index + 1)]
console.log(result)
I would do something like:
updatedObj = [obj1.map((entry) => entry.id !== newObj.id), newObj]
This would give me the updated object with minimal syntax

Returning new arrays using map in javascript [duplicate]

This question already has answers here:
Changing arrays using map in javascript
(7 answers)
Closed 4 years ago.
I am building one nodejs application where in req.body:
I have this object:
{
"id": 8,
"username": "sameer",
"age": "20"
"details": [
{
"category": {
"id": 1,
"nickname": "sam"
}
},
{
"category": {
"id": 2,
"nickname": "basha"
}
}
]
}
My expected output:
{
"id": 8,
"username": "sameer",
"age" : "20",
"final": [1,2] // this id coming from category id.
}
I tried this static way:
var data = 'myJsonStuffs'
var result = data.details.map(x => {
return({
"id": data.id,
"username": data.username,
"age": data.age,
"final": [1,2] // i want this dynamic
});
});
console.log(result);
How to do this using map? is this possible to return dynamic values.
You can use the function map:
Important: this approach will mutate the original obj.
var obj = { "id": 8, "username": "sameer", "age": "20", "details": [ { "category": { "id": 1, "nickname": "sam" } }, { "category": { "id": 2, "nickname": "basha" } } ]};
obj.final = obj.details.map((d) => d.category.id);
delete obj.details
console.log(obj)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Keeping the original obj structure
var obj = { "id": 8, "username": "sameer", "age": "20", "details": [ { "category": { "id": 1, "nickname": "sam" } }, { "category": { "id": 2, "nickname": "basha" } } ]};
var newObj = Object.assign({}, {
id: obj.id,
username: obj.username,
age: obj.age,
final: obj.details.map((d) => d.category.id)
});
console.log(newObj);
.as-console-wrapper { max-height: 100% !important; top: 0; }
This is how I'd do it.
I hope this helps
const data = {
id: 8,
username: "sameer",
age: "20",
details: [
{
category: {
id: 1,
nickname: "sam"
}
},
{
category: {
id: 2,
nickname: "basha"
}
}
]
};
const result = Object.assign(
{}, // Empty object to avoid mutating 'data'
data,
{ details: data.details.map(detail => detail.category.id) } // Override 'details'
);
console.log(result);
Maybe you want this?
you can use 'i' as index and populate arrays with that
var data = 'myJsonStuffs'
var result = data.details.map((x,i) => {
return({
"id": data.id,
"username": data.username,
"age": data.age,
"final": [i] // i want this dynamic
});
});
console.log(result);

Categories

Resources