Formatt array of obj - javascript

i have this array of obj
const pressure = [
{
date: "2021-11-03T23:51:55.875Z",
diastolica: 72,
pulsazione: 69,
sistolica: 130,
user: "61830313ba36bf2504df0ec3",
__v: 0,
_id: "6183209bf91a7ed54a76c05e",
},
{
date: "2021-11-03T23:52:09.684Z",
diastolica: 75,
pulsazione: 71,
sistolica: 135,
user: "61830313ba36bf2504df0ec3",
__v: 0,
_id: "618320a9f91a7ed54a76c061",
},
];
What I would like to get is an array of objects formatted like this
[
{
name: "Sistolica",
data: [130,135],
},
{
name: "Diastolica",
data: [72,75]
},
{
name: "Pulsazione",
data: [69,71],
},
],
For use within apex charts
The solution I found is not suitable and above all it is not reusable, if I passed an array that does not have the same keys that I indicated in my helper function, everything would be for the worse.
Can anyone help me with this?
I post the solution I had adopted, but I know it's really awful
export const setupGraphSeries = (data) => {
const sistolica = [];
const diastolica = [];
const pulsazione = [];
const formatter = data.map((item) => {
sistolica.push(item["sistolica"]);
diastolica.push(item["diastolica"]);
pulsazione.push(item["pulsazione"]);
return [
{ name: "Sistolica", data: sistolica },
{ name: "Diastolica", data: diastolica },
{ name: "Pulsazione", data: pulsazione },
];
});
return formatter;
};

One way is to just map over an array of the required properties. This does mean mapping over pressures once per item:
const pressure = [
{
date: "2021-11-03T23:51:55.875Z",
diastolica: 72,
pulsazione: 69,
sistolica: 130,
user: "61830313ba36bf2504df0ec3",
__v: 0,
_id: "6183209bf91a7ed54a76c05e",
},
{
date: "2021-11-03T23:52:09.684Z",
diastolica: 75,
pulsazione: 71,
sistolica: 135,
user: "61830313ba36bf2504df0ec3",
__v: 0,
_id: "618320a9f91a7ed54a76c061",
},
];
const params = ["diastolica","pulsazione","sistolica"];
const result = params.map( name => ({
name,
data: pressure.map(x => x[name])
}));
console.log(result);
Another way is to reduce the original keeping track of whether you have that item yet. This doesnt require multiple passes over the original data but is a little more complex:
const pressure = [
{
date: "2021-11-03T23:51:55.875Z",
diastolica: 72,
pulsazione: 69,
sistolica: 130,
user: "61830313ba36bf2504df0ec3",
__v: 0,
_id: "6183209bf91a7ed54a76c05e",
},
{
date: "2021-11-03T23:52:09.684Z",
diastolica: 75,
pulsazione: 71,
sistolica: 135,
user: "61830313ba36bf2504df0ec3",
__v: 0,
_id: "618320a9f91a7ed54a76c061",
},
];
const params = ["diastolica","pulsazione","sistolica"];
const result = Object.values(pressure.reduce( (a,item) => {
for(var i=0;i<params.length;i++){
const name = params[i];
a[name] = a[name] || {name,data:[]}
a[name].data.push(item[name]);
}
return a;
},{}));
console.log(result);

Related

Modify array of objects to replace with additional properties if null

I have an array of object as follows
let data = [
{
vertical_name: "CORE",
projects: [
{
name: "Alpha",
id: 187,
current_result: null,
}
]
},
{
vertical_name: "release",
projects: [
{
name: "Beta",
id: 27,
current_result: {
success_percentage: 37,
failure_percentage: 25,
skip_percentage: 36
}
},
{
name: "Charlie",
id: 47,
current_result: {
success_percentage: 37,
failure_percentage: 25,
skip_percentage: 36
}
}
]
}
]
As you can see current_result is null at one place. So i have to modify data to show that current_result is not tested. So in this case, instead of showing null, i want to show as follows. not_tested is 100 and skip, failure and success percentage is 0 in this case.
current_result: {
success_percentage: 0,
failure_percentage: 0,
skip_percentage: 0,
not_tested: 100
}
Also on other values of current_result, since it is not null and has success, failure and skip values, not_tested should be 0 for this.
The final result should look something like this. can someone please let me know how to achieve this as it is slightly complicated for me to come to a definitive answer
result = [
{
vertical_name: "CORE",
projects: [
{
name: "Alpha",
id: 187,
current_result: {
success_percentage: 0,
failure_percentage: 0,
skip_percentage: 0,
not_tested: 100
}
}
]
},
{
vertical_name: "release",
projects: [
{
name: "Beta",
id: 27,
current_result: {
success_percentage: 37,
failure_percentage: 25,
skip_percentage: 36,
not_tested: 0
}
},
{
name: "Charlie",
id: 47,
current_result: {
success_percentage: 37,
failure_percentage: 25,
skip_percentage: 36,
not_tested: 0
}
}
]
}
]
You could loop into data's projects array and insert keys you want in this way:
let data = [ { vertical_name: "CORE", projects: [ { name: "Alpha", id: 187, current_result: null, } ] }, { vertical_name: "release", projects: [ { name: "Beta", id: 27, current_result: { success_percentage: 37, failure_percentage: 25, skip_percentage: 36 } }, { name: "Charlie", id: 47, current_result: { success_percentage: 37, failure_percentage: 25, skip_percentage: 36 } } ] } ]
data.forEach(dat => {
dat.projects.forEach(prj => {
if (!prj.current_result) {
prj.current_result = {
success_percentage: 0,
failure_percentage: 0,
skip_percentage: 0,
not_tested: 100
};
}
else {
prj.current_result.not_tested = 0;
}
})
})
console.log(data)
Using Array#map without mutating the original data
const data = [{"vertical_name":"CORE","projects":[{"name":"Alpha","id":187,"current_result":null}]},{"vertical_name":"release","projects":[{"name":"Beta","id":27,"current_result":{"success_percentage":37,"failure_percentage":25,"skip_percentage":36}},{"name":"Charlie","id":47,"current_result":{"success_percentage":37,"failure_percentage":25,"skip_percentage":36}}]}];
const formatted = data.map(item => Object.assign(item, {
projects: item.projects.map(project => {
if (project.current_result === null) {
project.current_result = {
success_percentage: 0,
failure_percentage: 0,
skip_percentage: 0,
not_tested: 100
};
} else project.current_result.not_tested = 0;
return project;
})
}));
console.log(formatted);
let data = [{vertical_name: "CORE",projects: [{name: "Alpha",id: 187, current_result: null,}]},{vertical_name: "release", projects: [{ name: "Beta", id: 27, current_result: { success_percentage: 37, failure_percentage: 25, skip_percentage: 36}},{name: "Charlie", id: 47, current_result: { success_percentage: 37, failure_percentage: 25, skip_percentage: 36}}]}]
const newData = data.map((element)=>{
return element.projects.map((project)=>{
if(project.current_result === null){
return {...project, current_result: {success_percentage: 0,
failure_percentage: 0,
skip_percentage: 0,
not_tested: 100
}
}
}
return {...project, current_result: {...project.current_result, not_tested: 0} }
})
})
console.log(newData)
you can try this code :
data.map((element)=>{
element.projects.map((project)=>{
if(project.current_result === null){
return {...project, current_result: {success_percentage: 0,
failure_percentage: 0,
skip_percentage: 0,
not_tested: 100
}
}
}
return {...project, current_result: {...project.current_result, not_tested: 0} }
})
})
You can filter out your result data and assign a default value.
const result = data.map((item) => {
const projects = item.projects.map((project) => {
if (!project?.current_result) {
return {
...project,
current_result: {
success_percentage: 0,
failure_percentage: 0,
skip_percentage: 0,
not_tested: 100,
},
};
} else {
return project;
}
});
console.log(result)

How to merge duplicate array?

const data =
[{notification_id: 124, user_id: 10, story_id: 25, string: "liked on your story" }
{notification_id: 125, user_id: 12, story_id: 25, string: "liked on your story" }
{notification_id: 126, user_id: 15, story_id: 25, string: "liked on your story" }]
output: user 10,12 and 15 liked on your story ID 25
I want to show output like above. How to merge and show those like the output. Any idea?
You need to create a hash map, check the code snippet below:
const allData = [
{ name: 'John', story: 1 },
{ name: 'Ross', story: 2 },
{ name: 'Taylor', story: 1 },
{ name: 'Jimmy', story: 2 },
{ name: 'Amanda', story: 3 },
];
const hash = {};
for (let data of allData) {
if (data.story in hash) hash[data.story] = [...hash[data.story], { ...data }];
else hash[data.story] = [{ ...data }];
}
console.log(hash);
You should use Map, which is what I would suggest. The code below does the same thing but using Maps.
const allData = [
{ name: 'John', story: 1 },
{ name: 'Ross', story: 2 },
{ name: 'Taylor', story: 1 },
{ name: 'Jimmy', story: 2 },
{ name: 'Amanda', story: 3 },
];
const hash = new Map();
for(let data of allData) {
const currentVal = hash.get(data.story);
if (currentVal) hash.set(data.story, [...currentVal, {...data}])
else hash.set(data.story, [{...data}])
}
console.log(hash);
I cann't comment. So i write here!
Are you wanting ...
result = [
{
story_id : 25,
user_id : [10, 12, 15]
}
]
Right?
This is solution of me
const data =
[{notification_id: 124, user_id: 10, story_id: 25, string: "liked on your story" }
{notification_id: 125, user_id: 12, story_id: 25, string: "liked on your story" }
{notification_id: 126, user_id: 15, story_id: 25, string: "liked on your story" }]
var result = data.reduce((res, item) => {
let storyID = item.story_id;
if (typeof res[storyID] == 'undefined') {
res[storyID] = {
story_id: storyID,
user_id: []
}
}
res[storyID].user_id.push(item.user_id);
return res;
}, []);
result = Object.values(result);

How to ReMap an array of object into new array

I have this initial array:
const initialData = [
{
day: 1,
values: [
{
name: 'Roger',
score: 90,
},
{
name: 'Kevin',
score: 88,
},
{
name: 'Steve',
score: 80,
},
],
},
{
day: 2,
values: [
{
name: 'Roger',
score: 70,
},
{
name: 'Michael',
score: 88,
},
],
},
{
day: 3,
values: [
{
name: 'Steve',
score: 97,
},
],
},
];
to be converted into:
const result = [
{
name: 'Roger',
scores: [90, 70, null],
},
{
name: 'Kevin',
scores: [88, null, null],
},
{
name: 'Steve',
scores: [80, null, 97],
},
{
name: 'Michael',
scores: [null, 88, null],
},
];
I'm trying to use array map and create temporary array:
const holder = [];
initialData.map()
but to no avail
You can do this in a couple of steps - first reduce so you can index by name, and then map those entries to the format you expected
const initialData = [{day:1,values:[{name:"Roger",score:90},{name:"Kevin",score:88},{name:"Steve",score:80}]},{day:2,values:[{name:"Roger",score:70},{name:"Michael",score:88}]},{day:3,values:[{name:"Steve",score:97}]}];
var result = Object.entries(initialData.reduce( (acc,item) => {
item.values.forEach( v => {
if(!acc[v.name]) acc[v.name] = {};
acc[v.name][item.day] = v.score;
});
return acc;
},{})).map( ([name,days]) => ({
name,
scores: new Array(initialData.length).fill(null).map( (_,i) => days[i+1] || null)
}))
console.log(result);
You could use reduce and forEach to create one object for each name and then to get an array from that object you can just use Object.values method.
const data = [{"day":1,"values":[{"name":"Roger","score":90},{"name":"Kevin","score":88},{"name":"Steve","score":80}]},{"day":2,"values":[{"name":"Roger","score":70},{"name":"Michael","score":88}]},{"day":3,"values":[{"name":"Steve","score":97}]}]
const obj = data.reduce((r, { values }, i) => {
values.forEach(({ name, score }) => {
if (!r[name]) r[name] = { name, scores: Array(data.length).fill(null)}
r[name].scores[i] = score
})
return r;
}, {})
const result = Object.values(obj)
console.log(result)

Get Specific Key with Highest Value from a (JSON) Object

I'm getting data back from an API response and attempting to get the name of the pitch with the highest speed. Here is a sample of the API response.
{
page: 1,
total_pages: 4,
listings: [
{
name: "A.J. Burnett",
pitches: [
{
name: "4 Seam FB",
speed: 96,
control: 84,
},
{
name: "Knuckle Curve",
speed: 79,
control: 74,
},
{
name: "Sinker",
speed: 95,
control: 64,
},
{
name: "Changeup",
speed: 81,
control: 44,
}
]
},
{
name: "Joe Smitch",
pitches: [
{
name: "4 Seam FB",
speed: 91,
control: 82,
},
{
name: "Changeup",
speed: 69,
control: 44,
}
]
},
]
}
Here is what I've tried:
itemSet.forEach( (item) => {
let fastestPitch = Object.keys(item.pitches).reduce((a, b) => {
item.pitches[a] > item.pitches[b] ? item.pitches[a].name : item.pitches[b].name
});
});
However, this always returns the name of the LAST pitch in the array. I'm attempting to return the pitch with the highest speed.
Edit: I've also tried the following, but it returns an error.
itemSet.forEach( (item) => {
let fastestPitch = Object.keys(item.pitches).reduce((a, b) => {
item.pitches[a].speed > item.pitches[b].speed ? item.pitches[a].name : item.pitches[b].name
});
});
Error:
(node:80698) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'speed' of undefined
You can do something like this:
const data = {
page: 1,
total_pages: 4,
listings: [{
name: "A.J. Burnett",
pitches: [{
name: "4 Seam FB",
speed: 96,
control: 84,
},
{
name: "Knuckle Curve",
speed: 79,
control: 74,
},
{
name: "Sinker",
speed: 95,
control: 64,
},
{
name: "Changeup",
speed: 81,
control: 44,
}
]
},
{
name: "Joe Smitch",
pitches: [{
name: "4 Seam FB",
speed: 91,
control: 82,
},
{
name: "Changeup",
speed: 69,
control: 44,
}
]
},
]
}
const fastesPitches = data.listings.map(({ pitches }) => {
return pitches.reduce((a, c) => c.speed > a.speed ? c : a).name;
});
console.log(fastesPitches);
To extract the fastest of each, you can Array#map each of the entries in listings and then Array#reduce their entries in pitches like this:
let data = { page: 1, total_pages: 4, listings: [{ name: "A.J. Burnett", pitches: [{ name: "4 Seam FB", speed: 96, control: 84, }, { name: "Knuckle Curve", speed: 79, control: 74, }, { name: "Sinker", speed: 95, control: 64, }, { name: "Changeup", speed: 81, control: 44, } ] }, { name: "Joe Smitch", pitches: [{ name: "4 Seam FB", speed: 91, control: 82, }, { name: "Changeup", speed: 69, control: 44, } ] }, ] };
let fastestPitches = data.listings.map(obj => {
return obj.pitches.reduce((best, current) => {
return best.speed > current.speed ? best : current
}, {}).name
});
console.log(fastestPitches)
Note that when you reduce, the first argument (best, in this case) is the result of the previous callback. So if you return just the name, you won't know what the speed of it was. So, you traverse and compare the speeds, then return the entire object that was better. When this finishes, you get the name of the result.
You could take a complete dynamic approach which looks for any depth and return the object with the wanted highest property from the most nested objects.
function getHighest(object, key) {
return Object.values(object).reduce((r, o) => {
if (!o || typeof o !== 'object') return r;
if (key in o && (!r || r[key] < o[key])) return o;
var temp = getHighest(o, key);
if (temp && (!r || r[key] < temp[key])) return temp;
return r;
}, undefined);
}
var data = { page: 1, total_pages: 4, listings: [{ name: "A.J. Burnett", pitches: [{ name: "4 Seam FB", speed: 96, control: 84 }, { name: "Knuckle Curve", speed: 79, control: 74 }, { name: "Sinker", speed: 95, control: 64 }, { name: "Changeup", speed: 81, control: 44 }] }, { name: "Joe Smitch", pitches: [{ name: "4 Seam FB", speed: 91, control: 82 }, { name: "Changeup", speed: 69, control: 44 }] }] },
highest = getHighest(data, 'speed');
console.log(highest.name);
console.log(highest);

The output of the below code is NaN, Why? [duplicate]

This question already has answers here:
Calling reduce to sum array of objects returns NaN
(2 answers)
Closed 3 years ago.
Here, i am trying to add 'order_total' property. I have used reduce method, if try for only arrays, the same code is working properly, but when i implemented on array of objects it is resulting NaN.
var user = {
id: 16,
username: 'smith',
email: 'smith#gmail.com',
order: [
{
id: 71,
order_number: 'DCT-123',
order_total: 12000,
},
{
id: 71,
order_number: 'DCT-345',
order_total: 7000,
},
{
id: 71,
order_number: 'DCT-321',
order_total: 2000,
}
]
};
var result = user.order.reduce(function(a, b) {
return a.order_total + b.order_total;
});
console.log(result);
The parameter a in the reduce callback is the accumulator, not the property of the object. Refer here to learn more about reduce
var user = {
id: 16,
username: 'smith',
email: 'smith#gmail.com',
order: [
{
id: 71,
order_number: 'DCT-123',
order_total: 12000,
},
{
id: 71,
order_number: 'DCT-345',
order_total: 7000,
},
{
id: 71,
order_number: 'DCT-321',
order_total: 2000,
}
]
};
var result = user.order.reduce(function(a, b) {
return a+b.order_total;
},0);
console.log(result);
You return a number, not an object.
var result = user.order.reduce(function(a, b) {
// ^ object
// ^ object
return a.order_total + b.order_total; // number
});
You need a start value of zero and add the value of the property.
var user = {
id: 16,
username: 'smith',
email: 'smith#gmail.com',
order: [
{
id: 71,
order_number: 'DCT-123',
order_total: 12000,
},
{
id: 71,
order_number: 'DCT-345',
order_total: 7000,
},
{
id: 71,
order_number: 'DCT-321',
order_total: 2000,
}
]
};
var result = user.order.reduce(function(total, a) {
return total + a.order_total;
}, 0);
console.log(result);

Categories

Resources