Grouping the object by key for Chartjs bar chart - javascript

I'm trying to create bar chart using Chart.js. I got stuck trying to create grouped bar chart based on the status per user. So here's the data:
[{statusId: 0, firstName: "Joe", status: "appealed", count: 1},
{statusId: 0, firstName: "Jane", status: "approved", count: 100},
{statusId: 0, firstName: "Smith", status: "approved", count: 63},
{statusId: 0, firstName: "Mike", status: "approved", count: 63},
{statusId: 0, firstName: "Ken", status: "approved", count: 35},
{statusId: 0, firstName: "Kim", status: "approved", count: 193},
{statusId: 0, firstName: "Joe", status: "approved", count: 1},
{statusId: 0, firstName: "Jane", status: "closed", count: 1},
{statusId: 0, firstName: "Joe", status: "concluded", count: 1},
{statusId: 0, firstName: "Jane", status: "denied", count: 6},
{statusId: 0, firstName: "Smith", status: "denied", count: 9},
{statusId: 0, firstName: "Mike", status: "denied", count: 1},
{statusId: 0, firstName: "Mark", status: "denied", count: 8},
{statusId: 0, firstName: "Ken", status: "denied", count: 2},
{statusId: 0, firstName: "Kim", status: "denied", count: 20},
{statusId: 0, firstName: "Joe", status: "denied", count: 2},
{statusId: 0, firstName: "Joe", status: "transferred", count: 1}]
From this data, I need to create a chart for users in x-axis with count of each status for the user. It can be easily done in Chartjs by having array of datasets like the following:
datasets:[{
data: [//some counts for a group],
},
{
data: [// counts for another group],
}
// and so on
}]
The problem is I'll need to group these data based on the status. So, one solution I can think of is:
angular.forEeach(data, function(val)){
switch(val.status){
case 'approved':
// add count to an approved count array
break;
case 'appealed':
// add count to appealed count array
break;
}
}
But I think there're problems with this one. What if they create another status e.g. pending. Then I'll have to go back and change the code. Is there anyway I can group the objects by status and create an array of count data for each group that I can then use in datasets?
I just signed up for javascript course in pluralsight, so it'll still take me a while to learn advanced javascript. In the meantime, can anyone show me the proper and efficient way to solve this puzzle?
EXAMPLE
Chart.js requires data to be in the following format:
var data = {
labels: ['Joe', 'Jane', 'Smith', 'Mike', 'Ken', 'Kim', 'Mark'],
datasets: [
{
label: 'Appealed',
fillColor: '#382765',
data: [1,0,0,0,0,0,0]
},
{
label: 'Approved',
fillColor: '#7BC225',
data: [1, 100, 63, 63, 35, 193,0]
},
{
label: 'Denied',
fillColor: '#2196F3',
data: [2, 6, 9, 1, 2, 20, 8]
},
]
}
So, what's happening here is for each item in labels there's a count for the status i.e. label in data array inside datasets array. For e.g.: data array for Appealed label: 1 is the count of appealed for Joe and rest is 0 for all other users.

You could use a hash table as reference to the array with the same status and another hash table for indices of the names. then build the labels array and datasets.
var raw = [{ statusId: 0, firstName: "Joe", status: "appealed", count: 1 }, { statusId: 0, firstName: "Jane", status: "approved", count: 100 }, { statusId: 0, firstName: "Smith", status: "approved", count: 63 }, { statusId: 0, firstName: "Mike", status: "approved", count: 63 }, { statusId: 0, firstName: "Ken", status: "approved", count: 35 }, { statusId: 0, firstName: "Kim", status: "approved", count: 193 }, { statusId: 0, firstName: "JoeJoe", status: "approved", count: 1 }, { statusId: 0, firstName: "Jane", status: "closed", count: 1 }, { statusId: 0, firstName: "Joe", status: "concluded", count: 1 }, { statusId: 0, firstName: "Jane", status: "denied", count: 6 }, { statusId: 0, firstName: "Smith", status: "denied", count: 9 }, { statusId: 0, firstName: "Mike", status: "denied", count: 1 }, { statusId: 0, firstName: "Mark", status: "denied", count: 8 }, { statusId: 0, firstName: "Ken", status: "denied", count: 2 }, { statusId: 0, firstName: "Kim", status: "denied", count: 20 }, { statusId: 0, firstName: "Joe", status: "denied", count: 2 }, { statusId: 0, firstName: "Joe", status: "transferred", count: 1 }],
nameIndices = Object.create(null),
statusHash = Object.create(null),
data = { labels: [], datasets: [] };
raw.forEach(function (o) {
if (!(o.firstName in nameIndices)) {
nameIndices[o.firstName] = data.labels.push(o.firstName) - 1;
data.datasets.forEach(function (a) { a.data.push(0); });
}
if (!statusHash[o.status]) {
statusHash[o.status] = { label: o.status, fillcolor: 'f00', data: data.labels.map(function () { return 0; }) };
data.datasets.push(statusHash[o.status]);
}
statusHash[o.status].data[nameIndices[o.firstName]] = o.count;
});
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Related

How can I push a prop and its value to objects that don't have that specific property knowing that these objects are in an array of objects

what I want to achieve is:-
Loop through the peopleData array,
add a prop call it 'age' and give it a value of '-'
if one of the objects (array elements)
does not have the key 'age'
const peopleData = [
{ name: "Ann", age: 15, email: "ann#test.com", birthMonth: "Jan" },
{ name: "Bob", age: 19, email: "bob#test.com", birthMonth: "Mar" },
{ name: "Cam", age: 18, email: "cam#test.com", birthMonth: "Feb" },
{ name: "Dan" },
{ name: "Steve", birthMonth: "Jun" },
{ name: "Tyson", age: 20, birthMonth: "Dec" },
];
That what I tried to do and it did not work
const addAgeObj = {age: '-'}
const myArr = peopleData.map(personData=> {
if(!personData.age) {
peopleData.push(addAgeObj);
console.log(peopleData);
}
});
peopleData.push is wrong. You need to update the object, not to add new objects to the array.
const peopleData = [
{ name: "Ann", age: 15, email: "ann#test.com", birthMonth: "Jan" },
{ name: "Bob", age: 19, email: "bob#test.com", birthMonth: "Mar" },
{ name: "Cam", age: 18, email: "cam#test.com", birthMonth: "Feb" },
{ name: "Dan" },
{ name: "Steve", birthMonth: "Jun" },
{ name: "Tyson", age: 20, birthMonth: "Dec" },
];
const myArr = peopleData.map(personData=> {
return {...personData, age: personData.age || '-'}
});
console.log(myArr);
const addAgeObj = {age: '-'}
const peopleData = [
{ name: "Ann", age: 15, email: "ann#test.com", birthMonth: "Jan" },
{ name: "Bob", age: 19, email: "bob#test.com", birthMonth: "Mar" },
{ name: "Cam", age: 18, email: "cam#test.com", birthMonth: "Feb" },
{ name: "Dan" },
{ name: "Steve", birthMonth: "Jun" },
{ name: "Tyson", age: 20, birthMonth: "Dec" },
];
const myArr = peopleData.map(personData=> {
/* if(!personData.age) {
peopleData.push(addAgeObj);
console.log(peopleData);
}*/
if(!Object.keys(personData).includes("age"))
personData={...personData,addAgeObj}
return personData
});
console.log(myArr)
Try this
peopleData.push does is adding new object and override the existing object.So that is wrong and that is not what you want.so try this one.
const peopleData = [
{ name: "Ann", age: 15, email: "ann#test.com", birthMonth: "Jan" },
{ name: "Bob", age: 19, email: "bob#test.com", birthMonth: "Mar" },
{ name: "Cam", age: 18, email: "cam#test.com", birthMonth: "Feb" },
{ name: "Dan" },
{ name: "Steve", birthMonth: "Jun" },
{ name: "Tyson", age: 20, birthMonth: "Dec" },
];
const myArr = peopleData.map(personData=> {
if(!personData.age) {
let newobj={...personData,age:"-"};
return newobj;
}
else{
return personData;
}
});
console.log(myArr);

Can you skip a level in a nested object without knowing the key in Javascript?

Hi I have this object
15: {
name: "Jane",
age: 43,
children: {
32: {
name: "Janette",
age: 24,
children: {
487: {
name: "Alex",
age: 3,
children: [],
},
166: {
name: "Marcus",
age: 1,
children: [],
},
},
},
},
},
104: {
name: "Eric",
age: 24,
children: [],
},
};
I want to remove or and skip through directly to the children. But it is a random produced key value "between". How can I make a new array or just modify it since I don't know what the key will be?
I want it to be like this:
var object = [
{
name: "Jane",
age: 43,
children: [
{
name: "Janette",
age: 24,
children: [
{
name: "Alex",
age: 3,
children: [],
},
{
name: "Marcus",
age: 1,
children: [],
},
],
},
],
},
{
name: "Eric",
age: 43,
children: [],
},
];
So as you see in the code, the ID with numbers are gone in that object that I want to make. Can you jump directly to the children if they exist?
you can do something like this
const stripKeys = data => Object.values(data)
.map(d => ({
...d,
children: stripKeys(d.children)
}))
const data = {
15: {
name: "Jane",
age: 43,
children: {
32: {
name: "Janette",
age: 24,
children: {
487: {
name: "Alex",
age: 3,
children: [],
},
166: {
name: "Marcus",
age: 1,
children: [],
},
},
},
},
},
104: {
name: "Eric",
age: 24,
children: [],
},
};
console.log(stripKeys(data))

How to return an array with the first 2 elements in an object whose value properties are an array

I just want to return an array containing the first and second objects of the element.
The next 2 elements will be repeated after traversing the keys
Given the following object:
const object = {
a: [
{ name: "John", age: 32 },
{ name: "David", age: 23 },
{ name: "Justin", age: 28 },
{ name: "Arnauld", age: 35 }
],
b: [
{ name: "Ivan", age: 18 },
{ name: "Nekko", age: 13 },
{ name: "Lena", age: 25 }
],
c: [
{ name: "Ann", age: 19 },
{ name: "Nick", age: 14 }
]
};
the result I want is
[
{ name: "John", age: 32 },
{ name: "David", age: 23 },
{ name: "Ivan", age: 18 },
{ name: "Nekko", age: 13 },
{ name: "Ann", age: 19 },
{ name: "Nick", age: 14 },
{ name: "Justin", age: 28 },
{ name: "Arnauld", age: 35 },
{ name: "Lena", age: 25 }
]
As far as I understand what needs to be done, the answer will look like this:
const array = {
a: [
{name: "AA", age: 18},
{name: "BB", age: 22},
{name: "cc", age: 22}
],
b: [
{name: "CC", age: 18},
{name: "DD", age: 13}
],
c: [
{name: "EE", age: 18},
{name: "FF", age: 14}
]
};
const result = Object.values(array).reduce((buff, array) => {
buff.push(array[0], array[1]);
return buff;
}, []);
console.log(result);

Show nested array items react native

I have array of comments and their replies like this:
[
{
commentId: "5efd85d5b2eff7063b8ec802",
description: "some comment description",
isAnonymous: false,
createdAt: "2020-07-02T06:59:33.317Z",
currentUserLiked: 0,
likes: 0,
user: {
firstName: "ar",
lastName: "ar",
email: "test#email.com",
username: "sami",
isVerified: false,
},
children: [
{
commentId: "5efd86b7b2eff7063b8ec803",
parentId: "5efd85d5b2eff7063b8ec802",
description: "some comment description",
isAnonymous: false,
createdAt: "2020-07-02T07:03:19.405Z",
currentUserLiked: 0,
likes: 0,
user: {
firstName: "ar",
lastName: "ar",
email: "test#email.com",
username: "sami",
isVerified: false,
},
children: [
{
commentId: "5efd89c4b2eff7063b8ec805",
parentId: "5efd86b7b2eff7063b8ec803",
description: "Child of Child",
isAnonymous: false,
createdAt: "2020-07-02T07:16:20.717Z",
currentUserLiked: 0,
likes: 0,
user: {
firstName: "ar",
lastName: "ar",
email: "test#email.com",
username: "sami",
isVerified: false,
},
children: [],
},
],
},
{
commentId: "5efd8996b2eff7063b8ec804",
parentId: "5efd85d5b2eff7063b8ec802",
description: "Child of Child",
isAnonymous: false,
createdAt: "2020-07-02T07:15:34.341Z",
currentUserLiked: 0,
likes: 0,
user: {
firstName: "ar",
lastName: "ar",
email: "test#email.com",
username: "sami",
isVerified: false,
},
children: [],
},
],
},
];
and I want to show them as all children in same level in react native using flatList.
How can I do this?
Do I understand correctly?:
const comments = [{id: 1, children: [{id: 2, children: [{id: 3, children:[]}]}]}];
const flatComments = (list) => {
return list.flatMap(el => {
const {children, ...out} = el;
return [out, ...flatComments(children)];
});
};
flatComments(comments);
// [{id: 1}, {id: 2}, {id: 3}];

How to get unique Id for multiple duplicate properties

say we have a object:
var db = [
{Id: "201" , Player: "Jon",price: "3.99", loc: "NJ" },
{Id: "202", Player: "Sam",price: "4.22", loc: "PA" },
{Id: "203" ,Player: "Sam",price: "4.22", loc: "NY" },
{Id: "204", Player: "Bill",price: "3.22", loc: "TX" },
{Id: "205" ,Player: "Dave",price: "3.99", loc: "WA" },
{Id: "206" ,Player: "Dave",price: "3.99", loc: "WI" },
];
202&203 and 205&206 have similar values for player and price but I need just one id for similar values i.e, output should be 202,205.
Can someone help me with that.
You could filter it with a hash table for look up for the same player and price values.
var db = [{ Id: "201", Player: "Jon", price: "3.99", loc: "NJ" }, { Id: "202", Player: "Sam", price: "4.22", loc: "PA" }, { Id: "203", Player: "Sam", price: "4.22", loc: "NY" }, { Id: "204", Player: "Bill", price: "3.22", loc: "TX" }, { Id: "205", Player: "Dave", price: "3.99", loc: "WA" }, { Id: "206", Player: "Dave", price: "3.99", loc: "WI" }],
filtered = db.filter(function (a) {
var key = a.Player + '|' + a.price;
if (!this[key]) {
this[key] = true;
return true;
}
}, Object.create(null))
console.log(filtered);
I think this could be a summarized answer:
var db = [{ Id: "201", Player: "Jon", price: "3.99", loc: "NJ" }, { Id: "202", Player: "Sam", price: "4.22", loc: "PA" }, { Id: "203", Player: "Sam", price: "4.22", loc: "NY" }, { Id: "204", Player: "Bill", price: "3.22", loc: "TX" }, { Id: "205", Player: "Dave", price: "3.99", loc: "WA" }, { Id: "206", Player: "Dave", price: "3.99", loc: "WI" }];
var result = db.filter((v, k) =>
(k = v.Player + v.price) in this ? false :(this[k] = true));
console.log(result);

Categories

Resources