I have an array of objects, like so:
[
{
"_id": "5b09cc3495cb6c0487f1166b",
"name": "ccc",
"email": "ccc#gmail.com",
"phone": "790467522",
"kidsNo": "1",
"adultsNo": "1",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b09cc6095cb6c0487f1166c",
"name": "asd",
"email": "asd#asd.pl",
"phone": "790467522",
"kidsNo": "2",
"adultsNo": "3",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "12:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b0b1560c7b4fd0c33b2d52e",
"name": "dddd",
"email": "dddd#ddd.pl",
"phone": "123123112",
"kidsNo": "2",
"adultsNo": "1",
"fullDate": "2018/5/17",
"year": "2018",
"month": "5",
"day": "17",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
}
]
In the future this array will contain much more objects.
I'm trying to solve this using map and for it seems to be quite complicated.
That's the challenge:
how I can count how many objects have certain value? How can I get to know how many times someone booked something to day===1? The best result would be an array like this:
[{dayOne: 2}, {dayTwo: 5}, {dayThree:1}.......and so on],
where value is the value of how many times a day was booked(key), hence how many times certain object(with certain value) has appeared in the array?
Thank you in advance!
To count objects by a condition, you can use .filter --
let firstDayCount = arr.filter(x => x.day === "1").length;
To group the result by days, you can use .reduce --
let countByDays =
arr.reduce((res, { day }) => {
res[day] = res[day] || 0;
res[day] += 1;
return res;
}, {});
If you want to format your output, you can then use a dictionary of names --
let dayNames = { 1: "dayOne", 2: "dayTwo" /* and so on */}
let formattedResult =
Object.keys(countByDays)
.map(n => { [dayNames[n]]: countByDays[n] });
Note that using a .filter for counting creates an intermediate throw-away array. We're not storing a reference anywhere, so it has to be GCed soon, but if it really affects your performance measurably in a real-life scenario, you can use a .reduce instead -- something that is called "deforestation":)
let count = arr.reduce((cnt, el) => el.day === "1" ? cnt += 1 : cnt, 0);
It'll still create an intermediate anonymous object though -- a reducer function -- so if your profiler shows this place as a bottleneck, you might be best off using a for loop. As always in such cases, it's up to you to find the right spot between performance and readability in your own real-world scenarios.
To get result exactly in that format you can do this.
const objs = [
{
"_id": "5b09cc3495cb6c0487f1166b",
"name": "ccc",
"email": "ccc#gmail.com",
"phone": "790467522",
"kidsNo": "1",
"adultsNo": "1",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b09cc6095cb6c0487f1166c",
"name": "asd",
"email": "asd#asd.pl",
"phone": "790467522",
"kidsNo": "2",
"adultsNo": "3",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "12:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b0b1560c7b4fd0c33b2d52e",
"name": "dddd",
"email": "dddd#ddd.pl",
"phone": "123123112",
"kidsNo": "2",
"adultsNo": "1",
"fullDate": "2018/5/17",
"year": "2018",
"month": "5",
"day": "17",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
}
]
const days = [['dayOne', 1], ['dayTwo', 2], ['dayThree', 3]];
const res = days.reduce((acc, v) => {
const obj = {};
obj[v[0]] = objs.filter(x => x.day == v[1]).length;
return acc.concat(obj);
}, []);
console.log(res);
Note that you will need to extend the days array for every day you want to include like that. So If you want to include all 31 possible days, you need this.
const objs = [
{
"_id": "5b09cc3495cb6c0487f1166b",
"name": "ccc",
"email": "ccc#gmail.com",
"phone": "790467522",
"kidsNo": "1",
"adultsNo": "1",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b09cc6095cb6c0487f1166c",
"name": "asd",
"email": "asd#asd.pl",
"phone": "790467522",
"kidsNo": "2",
"adultsNo": "3",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "12:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b0b1560c7b4fd0c33b2d52e",
"name": "dddd",
"email": "dddd#ddd.pl",
"phone": "123123112",
"kidsNo": "2",
"adultsNo": "1",
"fullDate": "2018/5/17",
"year": "2018",
"month": "5",
"day": "17",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
}
]
const days = [['dayOne', 1], ['dayTwo', 2], ['dayThree', 3], ['dayFour', 4], ['dayFive', 5],
['daySix', 6], ['daySeven', 7], ['dayEight', 8], ['dayNine', 9], ['dayTen', 10],
['dayEleven', 11], ['dayTwelve', 12], ['dayThirten', 13], ['dayFourteen', 14],
['dayFifteen', 15], ['daySixteen', 16], ['daySeventeen', 17], ['dayEighteen', 18],
['dayNineteen', 19], ['dayTwenty', 20], ['dayTwentyone', 21], ['dayTwentytwo', 22],
['dayTwentythree', 23], ['dayTwentyfour', 24], ['dayTwentyfive', 25], ['dayTwentysix', 26],
['dayTwentyseven', 27], ['dayTwentyeight', 28], ['dayTwentynine', 29], ['dayThirty', 30],
['dayThirtyone', 31]];
const res = days.reduce((acc, v) => {
const obj = {};
obj[v[0]] = objs.filter(x => x.day == v[1]).length;
return acc.concat(obj);
}, []);
console.log(res);
Which in this example returns [{dayOne: 2}, {dayTwo: 0}, ..., {daySeventeen}: 1, {dayNineteen: 0}, ...]
An alternative is using the function reduce to group and count.
const array = [{"_id": "5b09cc3495cb6c0487f1166b","name": "ccc","email": "ccc#gmail.com","phone": "790467522","kidsNo": "1","adultsNo": "1","fullDate": "2018/5/1","year": "2018","month": "5","day": "1","chosenHour": "11:00","chosenRoom": "x","__v": 0},{"_id": "5b09cc6095cb6c0487f1166c","name": "asd","email": "asd#asd.pl","phone": "790467522","kidsNo": "2","adultsNo": "3","fullDate": "2018/5/1","year": "2018","month": "5","day": "1","chosenHour": "12:00","chosenRoom": "x","__v": 0},{"_id": "5b0b1560c7b4fd0c33b2d52e","name": "dddd","email": "dddd#ddd.pl","phone": "123123112","kidsNo": "2","adultsNo": "1","fullDate": "2018/5/17","year": "2018","month": "5","day": "17","chosenHour": "11:00","chosenRoom": "x","__v": 0}],
result = Object.values(array.reduce((a, {day}) => {
let key = `day${day}`;
(a[key] || (a[key] = {[key]: 0}))[key]++;
return a;
}, {}));
console.log(result);
Related
I have the JSON like
var resultJSON = `{
"data": {
"total": 1,
"list_name": "title",
"title": {
"id": 53,
"name": "Sonu",
"mobileNo": "6543213456",
"address": "Greeny Pathway",
"city": "NewYork",
"mode": "Weekly",
"duration": "15",
"qty": null
},
"download": [{
"time": "16789042",
"date": "26 - 01 - 2020"
}]
}
}`;
I expect the output:
{
"total": "1",
"list_name": "title",
"name": "sonu",
"mobileno": "6543213456"
}
Here "list_name": "title" is dynamic, sometimes it will come "list_name": "book", based on that above mentioned response I want to get.
Something like this? I had to fix your invalid JSON
You can make it more clever if you study https://javascript.info/destructuring-assignment in depth
const resultJSON = `{
"data": {
"total": 1,
"list_name": "title",
"title": {
"id": 53,
"name": "Sonu",
"mobileNo": "6543213456",
"address": "Greeny Pathway",
"city": "NewYork",
"mode": "Weekly",
"duration": "15",
"qty": null
},
"download": [{
"time": "16789042",
"date": "26-01-2020"
}]
}
}`
const data = JSON.parse(resultJSON).data
const content = data[data.list_name];
let newObj = {}
newObj["total"] = data["total"];
newObj["list_name"] = data["list_name"];
newObj["name"] = content["name"];
newObj["mobileNo"] = content["mobileNo"];
console.log(newObj)
I was doing some data manipulation, but I made a mistake and got the wrong data structure, so initially my data is: (link to data)
const employees = [{
"EmployeeID": "100A",
"FirstName": "Downs",
"aval": [
{"start": "11-19", "end": "2", "ava": "30", "health": "4"},
{"start": "11-20", "end": "2", "ava": "40", "health": "4"},
{"start": "11-21", "end": "2", "ava": "50", "health": "4"},
{"start": "11-22", "end": "2", "ava": "60", "health": "4"}
]
},
{
"EmployeeID": "100B",
"FirstName": "Mckenzie",
"aval": [
{"start": "11-19", "end": "2", "ava": "1", "health": "4"},
{"start": "11-20", "end": "2", "ava": "2", "health": "4"},
{"start": "11-21", "end": "2", "ava": "3", "health": "4"},
{"start": "11-22", "end": "2", "ava": "4", "health": "4"}
]
},
]
and would like to get it like:
const employees = [
{ "EmployeeID": "100A", "11-19": "30", "11-20": "40", "11-21": "50", "11-22": "60"},
{ "EmployeeID": "100B", "11-19": "1", "11-20": "2", "11-21": "3", "11-22": "4"}
]
I've asked around and this gives me 10 objects instead of two, just need to put those pesky employeeID inside 1 object with all the start values altogether.
const res = employees.reduce((acc, { EmployeeID, aval}) => [
...acc,
...aval.map( ({ start, ava}) => ({ EmployeeID, [start]: ava}) )
], []);
Because your input items and output items are one-to-one, you should use .map on employees instead of .reduce:
const employees=[{"EmployeeID":"100A","FirstName":"Downs","aval":[{"start":"11-19","end":"2","ava":"30","health":"4"},{"start":"11-20","end":"2","ava":"40","health":"4"},{"start":"11-21","end":"2","ava":"50","health":"4"},{"start":"11-22","end":"2","ava":"60","health":"4"}]},{"EmployeeID":"100B","FirstName":"Mckenzie","aval":[{"start":"11-19","end":"2","ava":"1","health":"4"},{"start":"11-20","end":"2","ava":"2","health":"4"},{"start":"11-21","end":"2","ava":"3","health":"4"},{"start":"11-22","end":"2","ava":"4","health":"4"}]},];
const res = employees.map(({ EmployeeID, aval }) => (
Object.assign(
{ EmployeeID },
...aval.map(({ start, ava }) => ({ [start]: ava }))
)
));
console.log(res);
Or, if you wanted to create fewer discarded intermediate objects, you could reduce the inner array aval instead of .map:
const employees=[{"EmployeeID":"100A","FirstName":"Downs","aval":[{"start":"11-19","end":"2","ava":"30","health":"4"},{"start":"11-20","end":"2","ava":"40","health":"4"},{"start":"11-21","end":"2","ava":"50","health":"4"},{"start":"11-22","end":"2","ava":"60","health":"4"}]},{"EmployeeID":"100B","FirstName":"Mckenzie","aval":[{"start":"11-19","end":"2","ava":"1","health":"4"},{"start":"11-20","end":"2","ava":"2","health":"4"},{"start":"11-21","end":"2","ava":"3","health":"4"},{"start":"11-22","end":"2","ava":"4","health":"4"}]},];
const res = employees.map(({ EmployeeID, aval }) => (
aval.reduce((a, { start, ava }) => {
a[start] = ava;
return a;
}, { EmployeeID })
));
console.log(res);
I have a json similar to this one
{
"id": "1",
"month": "January",
"type": "inc",
"Value": "780.00",
"year": "2018",
},
{
"id": "2",
"month": "January",
"type": "inc",
"Value": "80.00",
"year": "2018",
},
{
"id": "3",
"month": "February",
"type": "inc",
"Value": "100.00",
"year": "2018",
},...
Now I need to get all the Value from the object for all the months, as you can see I may have more objects with the same month name. The closer I got to was creating 2 arrays 1 with the list of Months and 1 with the value but I got stuck, can someone lead me to the correct path?
The desired output would be to get an array like that ["January"=>1500, "February"=>2000...] or have 2 arrays, 1 with the list of months where there is income (I already have it) and the second the total income for these months, so it's like this: ["January", "February", "March"..] and the second one [1500, 2000, 300...]
You can use the function Array.prototype.reduce to sum each Value by month.
let arr = [{ "id": "1", "month": "January", "type": "inc", "Value": "780.00", "year": "2018", }, { "id": "2", "month": "January", "type": "inc", "Value": "80.00", "year": "2018", }, { "id": "3", "month": "February", "type": "inc", "Value": "100.00", "year": "2018", }],
result = arr.reduce((a, {month, Value}) => {
a[month] = (a[month] || 0) + +Value;
return a;
}, Object.create(null));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I actually can barely understand what you would like to achieve. Please provide some example.
If I understood you correctly, you can use map function of js array to map each object to its Value.
let arr = [...];
console.log(arr.map(item => item.Value));
You can do
var fabuaryDate = yourdata
.filter(function(data) { return data.month == "February" })
.map(function(x){return {value: x.Value} })
To get result in following format :
{
jan : [1,2,3],
feb : [3,4,5,6],
april : [3,4,5]
}
do this :
var output = {}
arr.forEach(element => {
if(!output[element.month]){
output[month] = new Array();
}
output[month].push(element.value);
});
You can iterate the object and fill an array with the values of the field you want to extract, like so:
const data = [ {
"id": "1",
"month": "January",
"type": "inc",
"Value": 780.00,
"year": "2018",
},
{
"id": "2",
"month": "January",
"type": "inc",
"Value": 80.00,
"year": "2018",
},
{
"id": "3",
"month": "February",
"type": "inc",
"Value": 100.00,
"year": "2018",
}];
let dataArray = data.reduce((accum, d) => {
if(!accum[d.month]) accum[d.month] = 0;
accum[d.month] += d.Value;
return accum;
},{});
console.log(dataArray);
Although you don't seem to be clear enough with what have you tried here is an example of what you could do in order to read all the values inside the json.
function myFunction(item) {
console.log(item.month + " with the value " + item.Value)
}
var jsonArray = [{"id": "1","month": "January", "type": "inc", "Value": "780.00", "year": "2018" }, { "id": "2", "month": "January", "type": "inc", "Value": "80.00", "year": "2018" }, { "id": "3", "month": "February", "type": "inc", "Value": "100.00", "year": "2018" }];
jsonArray.forEach(myFunction);
Since you're working with an array of objects you must access to each of the objects in the array and then get the attribute that you require.
Hope this help, have a great day.
I need help regarding rendering this JSON data in html table using angular:
[{
"task": "Test1",
"number": 20,
"name": "John"
},
{
"task": "Test1",
"number": 10,
"name": "Doug"
},
{
"task": "Test2",
"number": 50,
"name": "John"
},
{
"task": "Test2",
"number": 100,
"name": "Doug"
}]
My rendered html table should look like this
Test1 Test2
John 20 50
Doug 10 100
Somehow values need to be grouped by, and then rendered, but to keep matching data. Also that first position in array[0][0] should be empty. Any help will be appreciated.
So you can group your data by name , and have Object of arrays like following :
{
"John": [
{
"task": "Test1",
"number": 20,
"name": "John"
},
{
"task": "Test2",
"number": 50,
"name": "John"
}
],
"Doug": [
{
"task": "Test1",
"number": 10,
"name": "Doug"
},
{
"task": "Test2",
"number": 100,
"name": "Doug"
}
]
}
Then , define a function to retrieve data by name & task : getItemBy=function(name,task)
Those two steps will make your algo easy to render HTML table as u want :
DEMO :
var data=[{
"task": "Test1",
"number": 20,
"name": "John"
},
{
"task": "Test1",
"number": 10,
"name": "Doug"
},
{
"task": "Test2",
"number": 50,
"name": "John"
},
{
"task": "Test2",
"number": 100,
"name": "Doug"
}];
var groupBy=function(arr,key) {
return arr.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
//------
var groupedByName=groupBy(data,'name');
var getItemBy=function(name,task){
return groupedByName[name].filter((item)=>item.task===task)
};
//------
//--
console.log(`***** Item where name=John & task=Test1`,
getItemBy('John','Test1')
)
console.log(`****** All data after grouping`,
groupedByName
)
I have a JSON object in a store that looks like the below. I am dynamically filtering values based on selections in a property grid. I am not filtering on the top level values (personName, primaryRole etc) but instead I want to drill down into the array of periods I have. For instance, I want to filter each record in the store for "periods" > "periodName".
I'm not sure how to do this, as it's not something I have come across before. Using combo.getStore().filter('periodName', gridvalues.periodName); does not work as it doesn't find the periodName, and I cannot simply use periods.periodName unfortunately.
"id": "531b0633-c9f5-4cbe-be69-5df4944b6e9b",
"personName": "Ben",
"primaryRole": "SWE",
"secondaryRole": "SWE",
"periods": [
{
"personName": "Ben",
"periodName": "Week 24",
"teamName": "Tango",
"experience": 2,
"periodNumber": 24,
"id": "71d514c2-a39f-40b7-af9e-51fbf30b2a48"
},
{
"personName": "Ben",
"periodName": "Week 25",
"teamName": "-",
"experience": "-",
"periodNumber": 25,
"id": "49505fb2-97df-4f45-a11d-bb22c110a422"
},
{
"personName": "Ben",
"periodName": "Week 26",
"teamName": "-",
"experience": "-",
"periodNumber": 26,
"id": "97f2b272-c23c-4320-a1ce-09dadf0c6b5d"
},
"id": "7037ad16-dcbe-4326-8547-65108c03c874",
"personName": "Luke",
"primaryRole": "Product Owner",
"secondaryRole": "SWE",
"periods": [
{
"personName": "Luke",
"periodName": "Week 24",
"teamName": "Tango",
"experience": 3,
"periodNumber": 24,
"id": "e3184bef-c330-4219-ae21-8b65efcde77c"
},
{
"personName": "Luke",
"periodName": "Week 25",
"teamName": "-",
"experience": "-",
"periodNumber": 25,
"id": "f431af7b-8060-40d2-8464-af533d943363"
},
This is a record from my store:
id: "531b0633-c9f5-4cbe-be69-5df4944b6e9b"periodNumber: 0periods: Array[16]0: Objectexperience: 2id: "71d514c2-a39f-40b7-af9e-51fbf30b2a48"periodName: "Week 24"periodNumber: 24personName: "Ben"teamName: "Tango"__proto__: Object1: Object2: Object3: Object4: Object5: Object6: Object7: Object8: Object9: Object10: Object11: Object12: Object13: Object14: Object15: Objectlength: 16__proto__: Array[0]personName: "Ben"primaryRole: "SWE"secondaryRole: "SWE"
Use the addFilter function in your controller:
combo.getStore().addFilter({property: 'yourProperty', value: 'valueToFilter'});
For more info:
http://docs.sencha.com/extjs/4.2.3/#!/api/Ext.data.Store-method-addFilter