To display data in highcharts.js I need to turn the following data:
"personas": [
{
"category":"Persona1",
"month":"6",
"week":"24",
"day":"18",
"dayaverage":0.5,
"weekaverage":1.33333333333333,
"monthaverage":1.53571428571429
},
{
"category":"Persona2",
"month":"6",
"week":"24",
"day":"18",
"dayaverage":0.146477031224456,
"weekaverage":0.194758246723904,
"monthaverage":0.601273296708939
},
{
"category":"Persona3",
"month":"6",
"week":"24",
"day":"18",
"dayaverage":1.25559947299078,
"weekaverage":1.43618513323983,
"monthaverage":0.998426393184655
},
{
"category":"Persona4",
"month":"6",
"week":"24",
"day":"18",
"dayaverage":0.799332962757087,
"weekaverage":0.923262727610554,
"monthaverage":0.769477297163179
},
{
"category":"Persona5",
"month":"6",
"week":"24",
"day":"18",
"dayaverage":0.669041769041769,
"weekaverage":0.67394482002558,
"monthaverage":0.670944920469891
},
{
"category":"Persona6",
"month":"6",
"week":"24",
"day":"18",
"dayaverage":0.656381486676017,
"weekaverage":0.722973507315144,
"monthaverage":0.69689774371321
},
{
"category":"Persona7",
"month":"6",
"week":"24",
"day":"18",
"dayaverage":0.540495407737267,
"weekaverage":0.576413277444205,
"monthaverage":0.693495281755596
}
]
Into this format:
[
{
name: 'dayaverage',
data: [0.5, 0.146477031224456, 1.25559947299078, 0.799332962757087, 0.669041769041769, 0.656381486676017, 0.540495407737267]
},
{
name: 'weekaverage',
data: [1.33333333333333, 0.194758246723904, 1.43618513323983, 0.923262727610554, 0.67394482002558, 0.722973507315144, 0.576413277444205]
}, {
name: 'monthaverage',
data: [1.53571428571429, 0.601273296708939, 0.998426393184655, 0.769477297163179, 0.670944920469891, 0.69689774371321, 0.693495281755596]
}
].
All I'm doing is grouping the dayaverage, weekaverage and monthaverage values into an array and specifying what they are with a name key-value pair.
I'm having trouble writing this because the parent function is going to call with a list of criteria (for the above example it was : criteria = ['dayaverage', 'weekaverage', 'monthaverage'];) and that could change.
Any help appreciated, thanks
You could use an array for the wanted properties and build an array with the data upon.
function getGrouped(array, groups) {
var grouped = groups.map(function (a) {
return { name: a, data: [] };
});
array.personas.forEach(function (a) {
groups.forEach(function (k, i) {
grouped[i].data.push(a[k]);
});
});
return grouped;
}
var data = { personas: [{ category: "Persona1", month: 6, week: 24, day: 18, dayaverage: 0.5, weekaverage: 1.33333333333333, monthaverage: 1.53571428571429 }, { category: "Persona2", month: 6, week: 24, day: 18, dayaverage: 0.146477031224456, weekaverage: 0.194758246723904, monthaverage: 0.601273296708939 }, { category: "Persona3", month: 6, week: 24, day: 18, dayaverage: 1.25559947299078, weekaverage: 1.43618513323983, monthaverage: 0.998426393184655 }, { category: "Persona4", month: 6, week: 24, day: 18, dayaverage: 0.799332962757087, weekaverage: 0.923262727610554, monthaverage: 0.769477297163179 }, { category: "Persona5", month: 6, week: 24, day: 18, dayaverage: 0.669041769041769, weekaverage: 0.67394482002558, monthaverage: 0.670944920469891 }, { category: "Persona6", month: 6, week: 24, day: 18, dayaverage: 0.656381486676017, weekaverage: 0.722973507315144, monthaverage: 0.69689774371321 }, { category: "Persona7", month: 6, week: 24, day: 18, dayaverage: 0.540495407737267, weekaverage: 0.576413277444205, monthaverage: 0.693495281755596 }] };
console.log(getGrouped(data, ['day', 'dayaverage', 'weekaverage', 'monthaverage']));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can do this using .map() along with .reduce() like so:
Also, to use dynamic properties, you can use bracket syntax ([]) for accessing properties on an object. Here, you can .map() your criteria list into the desired structure, and calculate the data using .reduce().
EDIT - Fixed resulting data structure to accurately output desired results
var personas = [{
"category": "Persona1",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.5,
"weekaverage": 1.33333333333333,
"monthaverage": 1.53571428571429
},
{
"category": "Persona2",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.146477031224456,
"weekaverage": 0.194758246723904,
"monthaverage": 0.601273296708939
},
{
"category": "Persona3",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 1.25559947299078,
"weekaverage": 1.43618513323983,
"monthaverage": 0.998426393184655
},
{
"category": "Persona4",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.799332962757087,
"weekaverage": 0.923262727610554,
"monthaverage": 0.769477297163179
},
{
"category": "Persona5",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.669041769041769,
"weekaverage": 0.67394482002558,
"monthaverage": 0.670944920469891
},
{
"category": "Persona6",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.656381486676017,
"weekaverage": 0.722973507315144,
"monthaverage": 0.69689774371321
},
{
"category": "Persona7",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.540495407737267,
"weekaverage": 0.576413277444205,
"monthaverage": 0.693495281755596
}
];
var criteria = ['dayaverage', 'weekaverage', 'monthaverage'];
function getMerged(objArr, criteria) {
var dataMap = objArr.reduce(function (result, current) {
criteria.forEach(function (elem) {
if (result[elem] != undefined) {
result[elem].push(current[elem]);
}
else {
result[elem] = [current[elem]];
}
});
return result;
}, {});
return criteria.map(function (elem) {
return {
name: elem,
data: dataMap[elem]
};
});
}
console.log(getMerged(personas, criteria));
One of the ways how to solve it, using Array#forEach.
var json = {personas:[{category:"Persona1",month:"6",week:"24",day:"18",dayaverage:.5,weekaverage:1.33333333333333,monthaverage:1.53571428571429},{category:"Persona2",month:"6",week:"24",day:"18",dayaverage:.146477031224456,weekaverage:.194758246723904,monthaverage:.601273296708939},{category:"Persona3",month:"6",week:"24",day:"18",dayaverage:1.25559947299078,weekaverage:1.43618513323983,monthaverage:.998426393184655},{category:"Persona4",month:"6",week:"24",day:"18",dayaverage:.799332962757087,weekaverage:.923262727610554,monthaverage:.769477297163179},{category:"Persona5",month:"6",week:"24",day:"18",dayaverage:.669041769041769,weekaverage:.67394482002558,monthaverage:.670944920469891},{category:"Persona6",month:"6",week:"24",day:"18",dayaverage:.656381486676017,weekaverage:.722973507315144,monthaverage:.69689774371321},{category:"Persona7",month:"6",week:"24",day:"18",dayaverage:.540495407737267,weekaverage:.576413277444205,monthaverage:.693495281755596}]},
criteria = ['dayaverage', 'weekaverage', 'monthaverage'],
arr = criteria.reduce(function(s,a){
s.push({name: a, data: []});
return s;
}, []);
arr.forEach(function(v) {
json.personas.forEach(function(c) {
v.data.push(c[v.name]);
})
})
console.log(arr);
try this:
var criteria = ['dayaverage', 'weekaverage', 'monthaverage']; //your dynamic criteria
var arr= []; //the filtered array you want
criteria.forEach(function(criterium){
// for each criterium you create a new object that you add to arr
arr.push({
name: criterium,
data: []
});
// then you populate the data field of the newly created field by browsing your big array "personas" that you need to parse before btw
personas.forEach(function (persona) {
arr[arr.length-1].data.push(persona[criterium]);
});
});
You can map the keys to an array of objects and map each of the objects' values by the current key in the mapping process.
var data = getData();
var modified = modify(data, 'personas', ['dayaverage', 'weekaverage', 'monthaverage']);
console.log(JSON.stringify(modified, null, 2));
function modify(data, root, keep) {
data = data[root] != null ? data[root] : data;
var keys = Object.keys(data[0]);
if (keep != null && keep.length > 0)
keys = keys.filter(key => keep.indexOf(key) > -1);
return keys.map(key => {
return {
name: key,
data: data.map(item => item[key])
}
});
}
function getData() {
return {
"personas": [{
"category": "Persona1",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.5,
"weekaverage": 1.33333333333333,
"monthaverage": 1.53571428571429
}, {
"category": "Persona2",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.146477031224456,
"weekaverage": 0.194758246723904,
"monthaverage": 0.601273296708939
}, {
"category": "Persona3",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 1.25559947299078,
"weekaverage": 1.43618513323983,
"monthaverage": 0.998426393184655
}, {
"category": "Persona4",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.799332962757087,
"weekaverage": 0.923262727610554,
"monthaverage": 0.769477297163179
}, {
"category": "Persona5",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.669041769041769,
"weekaverage": 0.67394482002558,
"monthaverage": 0.670944920469891
}, {
"category": "Persona6",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.656381486676017,
"weekaverage": 0.722973507315144,
"monthaverage": 0.69689774371321
}, {
"category": "Persona7",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.540495407737267,
"weekaverage": 0.576413277444205,
"monthaverage": 0.693495281755596
}]
};
}
.as-console-wrapper { top: 0; max-height: 100% !important; }
Related
I made a line change via axios.path, but after changes in db.json I constantly need to reload the page. How can I avoid this and make the data update automatically?
const submitEdits = (item) => {
axios.patch(`http://localhost:3004/item/${item.id}`, { text: editingText })
setIdItem(null);
setEditingText('')
}
My db.json
{
"item": [
{
"text": "123123123",
"id": 0,
"data": {
"year": 2012,
"day": 25,
"month": 1
}
},
{
"text": "Поступил в институт",
"id": 1,
"data": {
"year": 2007,
"day": 12,
"month": 4
}
},
{
"id": 2,
"text": "123",
"data": {
"year": 2022,
"day": 16,
"month": 5
}
}
]
}
I have an array below like this
[
{
"Date": "2020-07",
"data": [
{
"id": "35ebd073-600c-4be4-a750-41c4be5ed24a",
"Date": "2020-07-03T00:00:00.000Z",
"transactionId": "13",
"transactionType": "Payment",
"amount": 1500
}
]
},
{
"Date": "2020-07",
"data": [
{
"id": "4e126519-e27b-4e82-bb81-689c7dc63c9b",
"Date": "2020-07-02T00:00:00.000Z",
"transactionId": "4",
"transactionType": "Payment",
"amount": 1000
}
]
},
{
"Date": "2020-06",
"data": [
{
"id": "646d6497-9dea-4f27-896e-a45d97a252ea",
"Date": "2020-06-04T00:00:00.000Z",
"transactionId": "14",
"transactionType": "Payment",
"amount": 1500
}
]
},
{
"Date": "2020-06",
"data": [
{
"id": "cf44e27f-2111-462d-b3bd-420a193745b8",
"Date": "2020-06-02T00:00:00.000Z",
"transactionId": "5",
"transactionType": "Payment",
"amount": 1000
}
]
}
]
Here there is key Date and there are two values for the same date key. Now I want if Date is same then data array record should merged.
So i expect output as
[
{
"Date": "2020-07",
"data": [
{
"id": "35ebd073-600c-4be4-a750-41c4be5ed24a",
"Date": "2020-07-03T00:00:00.000Z",
"transactionId": "13",
"transactionType": "Payment",
"amount": 1500
},
{
"id": "4e126519-e27b-4e82-bb81-689c7dc63c9b",
"Date": "2020-07-02T00:00:00.000Z",
"transactionId": "4",
"transactionType": "Payment",
"amount": 1000
}
]
},
{
"Date": "2020-06",
"data": [
{
"id": "646d6497-9dea-4f27-896e-a45d97a252ea",
"Date": "2020-06-04T00:00:00.000Z",
"transactionId": "14",
"transactionType": "Payment",
"amount": 1500
},
{
"id": "cf44e27f-2111-462d-b3bd-420a193745b8",
"Date": "2020-06-02T00:00:00.000Z",
"transactionId": "5",
"transactionType": "Payment",
"amount": 1000
}
]
}
]
Please tell me best-optimized way of doing it ?
You can use a dictionary and easily check if the key already exists and then append the new data, otherwise you will add the date as a new key.
var dict = {};
if (!("xxxx-xx" in dict)){ //if the key is not the dict
dict["xxxx-xx"] = [{ //we are storing an array because we want to add other later
id: "....",
transactionId: "..."
//etc...
}]
}
else { //if the key already exists, we push new data to the array
dict["xxxx-xx"].push({ //you can use push because is an array of objects
id: "....",
transactionId: "..."
//etc...
})
}
I hope that it can be helpful. An array would be less convenient to check if a key already exists and to avoid duplicates (by default with dict/object).
arr = your data set
obj = this will be your output
arr.forEach((elem) => {
if(obj[elem.Date]) {
obj[elem.Date].data.push(elem.data);
} else {
obj[elem.Date] = {
data: [elem.data]
}
}
});
First you have to group that array of objects by property Date. And iterate that grouped by key-value pairs of [Date, groupsByDate] then grab data from each group
const res = _.chain(data)
.groupBy("Date")
.toPairs()
.map(([key, value]) => ({
Date: key,
data: _.flatMap(value, "data"),
}))
.value()
Full code
const data = [
{
Date: "2020-07",
data: [
{
id: "35ebd073-600c-4be4-a750-41c4be5ed24a",
Date: "2020-07-03T00:00:00.000Z",
transactionId: "13",
transactionType: "Payment",
amount: 1500,
},
],
},
{
Date: "2020-07",
data: [
{
id: "4e126519-e27b-4e82-bb81-689c7dc63c9b",
Date: "2020-07-02T00:00:00.000Z",
transactionId: "4",
transactionType: "Payment",
amount: 1000,
},
],
},
{
Date: "2020-06",
data: [
{
id: "646d6497-9dea-4f27-896e-a45d97a252ea",
Date: "2020-06-04T00:00:00.000Z",
transactionId: "14",
transactionType: "Payment",
amount: 1500,
},
],
},
{
Date: "2020-06",
data: [
{
id: "cf44e27f-2111-462d-b3bd-420a193745b8",
Date: "2020-06-02T00:00:00.000Z",
transactionId: "5",
transactionType: "Payment",
amount: 1000,
},
],
},
]
const res = _.chain(data)
.groupBy("Date")
.toPairs()
.map(([key, value]) => ({
Date: key,
data: _.flatMap(value, "data"),
}))
.value()
console.log(JSON.stringify(res, null, 2))
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.20/lodash.min.js"></script>
I have a Json that looks like this
{
"score": "1200.65",
"num_games": "160",
"wins": "110",
"year": "2013"
},
{
"score": "705.23",
"num_games": "34",
"wins": "21",
"year": "2014"
},
{
"score": "467.12",
"num_games": "77",
"wins": "30",
"year": "2015"
},
I'd like to create an array of objects (containing x and y) that can be filtered by a range of years (for example years between 2014 and 2015) for the x property, and a specific property's value as the y (for example "score").
For example, if I filter by range of years 2014-2015 and by property "score", the resulting array should be:
[{x:'2014', y: 705.23}, {x:'2015', y: 467.12}]
Another example, if I filter by range of years 2014-2015 and by property "num_games", the resulting array should be:
[{x:'2014', y: 34}, {x:'2015', y: 77}]
How should i go about this? Is Array.prototype.filter the right tool for this?
Filter the array using Array#filter
Convert the elements of the array to a type of your choosing using Array#map
var data = [{"score": "1200.65", "num_games": "160", "wins": "110", "year": "2013" }, { "score": "705.23", "num_games": "34", "wins": "21", "year": "2014" }, { "score": "467.12", "num_games": "77", "wins": "30", "year": "2015" }];
function getFilteredData(data, start, end) {
return data.filter(function(item) {
return +start <= +item.year && +item.year <= +end;
}).map(function(item) {
return {
x: item.year,
y: item.score
};
});
}
console.log(getFilteredData(data, 2014, 2017));
If your dates are within reasonable boundaries you don't have to convert the year to a number but any 3- or 5+ digit years will not filter properly, unless you convert the years to numbers.
If you want a more abstract version of the function you could do:
var data = [{"score": "1200.65", "num_games": "160", "wins": "110", "year": "2013" }, { "score": "705.23", "num_games": "34", "wins": "21", "year": "2014" }, { "score": "467.12", "num_games": "77", "wins": "30", "year": "2015" }];
function getFilteredData(data, filterOptions, mapOptions) {
return data.filter(function(item) {
return Object.keys(filterOptions).every(function(key) {
var option = filterOptions[key];
if (+option.min <= +item[key] && +item[key] <= +option.max) return true;
});
}).map(function(item) {
return Object.keys(mapOptions).reduce(function(result, key) {
var option = mapOptions[key];
result[key] = item[option];
return result;
}, {});
});
}
function registerFilter(filterOptions, mapOptions) {
return function(data) {
return getFilteredData(data, filterOptions, mapOptions);
};
}
var customFilter = registerFilter(
{ year: { min: 2014, max: 2015 },
{ x: "year", y: "score" }
);
console.log(customFilter(data));
You could do both operations together using a for loop or Array#reduce. Which makes the code faster but less maintainable.
var data = [{"score": "1200.65", "num_games": "160", "wins": "110", "year": "2013" }, { "score": "705.23", "num_games": "34", "wins": "21", "year": "2014" }, { "score": "467.12", "num_games": "77", "wins": "30", "year": "2015" }];
function getFilteredData(data, start, end) {
return data.reduce(function(result, item) {
if (+start <= +item.year && +item.year <= +end) result.push({
x: item.year,
y: item.score
});
return result;
}, []);
}
console.log(getFilteredData(data, 2014, 2017));
Filter , Map , Object Destructing can do the job :
const y = [{
"score": "1200.65",
"num_games": "160",
"wins": "110",
"year": "2013"
},
{
"score": "705.23",
"num_games": "34",
"wins": "21",
"year": "2014"
},
{
"score": "467.12",
"num_games": "77",
"wins": "30",
"year": "2015"
}
];
const res = y.filter(o => o.year == 2014).map(({
year: x,
score: y
}) => ({
x,
y
}))
console.log(res)
You could filter and map the wanted values.
function getParts(array, [min, max], key) {
return array
.filter(({ year }) => +min <= year && year <= +max)
.map(({ year: x, [key]: y }) => ({ x, y }));
}
var data = [{ score: "1200.65", num_games: "160", wins: "110", year: "2013" }, { score: "705.23", num_games: "34", wins: "21", year: "2014" }, { score: "467.12", num_games: "77", wins: "30", year: "2015" }];
console.log(getParts(data, [2014, 2015], 'score'));
console.log(getParts(data, [2014, 2015], 'num_games'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use .filter to get the objects within your required range, and then use .map to create the objects from the filtered list.
See example below:
const arr = [{
"score": "1200.65",
"num_games": "160",
"wins": "110",
"year": "2013"
},
{
"score": "705.23",
"num_games": "34",
"wins": "21",
"year": "2014"
},
{
"score": "467.12",
"num_games": "77",
"wins": "30",
"year": "2015"
}];
const get_items = (arr, [sY, eY], prop) =>
arr
.filter(({year}) => +sY <= year && year <= +eY)
.map(({year:x, ...rest}) => ({x, y: rest[prop]}));
console.log(get_items(arr, ["2014", "2015"], "score"));
First filter the array by dates, then map the filtered items to your required format. You can use destructuring to make the code shorter:
const data = [{
"score": "1200.65",
"num_games": "160",
"wins": "110",
"year": "2013"
}, {
"score": "705.23",
"num_games": "34",
"wins": "21",
"year": "2014"
}, {
"score": "467.12",
"num_games": "77",
"wins": "30",
"year": "2015"
}];
const filterBy = (data, [min, max], prop) => data
.filter(({ year }) => year >= min && year <= max)
.map(({ year: x, [prop]: y }) => ({ x, y }));
console.log(filterBy(data, [2013, 2014], 'score'));
console.log(filterBy(data, [2013, 2013], 'wins'));
I am using destructuring to create a start and end time:
const {
startYear: year,
startMonth: month,
startDay: day,
startHour: hour,
startMinute: minute
} = event.start_date_details;
const {
endHour: hour,
endMinute: minute
} = event.end_date_details;
Any ideas?
Events json:
"events": [
{
"id": 518,
"global_id": "wordpress.rguc.co.uk?id=518",
"global_id_lineage": [
"wordpress.rguc.co.uk?id=518"
],
"author": "1",
"status": "publish",
"date": "2017-12-14 12:11:42",
"date_utc": "2017-12-14 12:11:42",
"modified": "2018-01-11 10:04:49",
"modified_utc": "2018-01-11 10:04:49",
"url": "http://wordpress.rguc.co.uk/event/another-one/",
"rest_url": "http://wordpress.rguc.co.uk/wp-json/tribe/events/v1/events/518",
"title": "another one",
"description": "",
"excerpt": "",
"image": false,
"all_day": true,
"start_date": "2018-01-31 00:00:00",
"start_date_details": {
"year": "2018",
"month": "01",
"day": "31",
"hour": "00",
"minutes": "00",
"seconds": "00"
},
"end_date": "2018-01-31 23:59:59",
"end_date_details": {
"year": "2018",
"month": "01",
"day": "31",
"hour": "23",
"minutes": "59",
"seconds": "59"
},
"utc_start_date": "2018-01-31 00:00:00",
"utc_start_date_details": {
"year": "2018",
"month": "01",
"day": "31",
"hour": "00",
"minutes": "00",
"seconds": "00"
},
"utc_end_date": "2018-01-31 23:59:59",
"utc_end_date_details": {
"year": "2018",
"month": "01",
"day": "31",
"hour": "23",
"minutes": "59",
"seconds": "59"
},
The syntax for destructuring (BTW destructing is the wrong term) is different. You need to specify keys you match before colon and variables you declare after colon.
Maybe you wanted:
const {
year: startYear,
month: startMonth,
day: startDay,
hour: startHour,
minutes: startMinute
} = event.start_date_details;
const {
hour: endHour,
minutes: endMinute
} = event.end_date_details;
You're destructuring both event.start_date_details.startHour and event.end_date_details.endHour to const hour. Change it to
const {
start_date_details: {
year: startYear,
month: startMonth,
day: startDay,
hour: startHour,
minutes: startMinute
},
end_date_details: {
hour: endHour,
minutes: endMinute
}
} = event;
so that you have the variable startHour, startMinute, endHour, and endMinute instead mapped from event.(start/end)_date_details.(hour/minutes).
See MDN's Destructuring Assignment - Assigning to new variable names.
Following code gets the result below in a way that multiple iterations required. I wonder what would be the way to make it happen in a single or less iterations. Thanks in advance.
var input = [{
"ActiveMembers": [{
"Id": 101,
"Name": "alpha"
}, {
"Id": 102,
"Name": "bravo"
}],
"Contents": [{
"Id": 2001,
"RowId": "517",
"Time": "19 Jan 2017",
"ViewCount": 1124
}, {
"Id": 2002,
"RowId": "518",
"Time": "Today, 07:02 PM",
"ViewCount": 62
}],
"TotalUsers": 3,
"UsersDetails": "2 members, 1 anonymous users"
}, {
"ActiveMembers": [{
"Id": 101,
"Name": "alpha"
}, {
"Id": 103,
"Name": "charlie"
}, {
"Id": 104,
"Name": "delta"
}, {
"Id": 105,
"Name": "bravo"
}],
"Contents": [{
"Id": 2002,
"RowId": "519",
"Time": "27 Jun 2017",
"ViewCount": 4833
}, {
"Id": 2041,
"RowId": "525",
"Time": "17 Feb 2015",
"ViewCount": 24491
}],
"TotalUsers": 23,
"UsersDetails": "4 members, 19 anonymous users"
}];
var contents = Array.prototype.concat.apply([], input.map(i => i.Contents));
var activeMembers = _.uniqBy(Array.prototype.concat.apply([], input.map(i => i.ActiveMembers)), (i) => i.Id);
var totalUsers = number = _.sumBy(input, (i) => i.TotalUsers);
var userDetails = string = input.map(i => i.UsersDetails).join(' ; ');
const result = new Object();
result.Contents = contents;
result.ActiveMembers = activeMembers;
result.TotalUsers = totalUsers;
result.UserDetails = userDetails;
console.log(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Result
{
"ActiveMembers": [
{
"Id": 101,
"Name": "alpha"
},
{
"Id": 102,
"Name": "bravo"
},
{
"Id": 103,
"Name": "charlie"
},
{
"Id": 104,
"Name": "delta"
},
{
"Id": 105,
"Name": "bravo"
}
],
"Contents": [
{
"Id": 2001,
"RowId": "517",
"Time": "19 Jan 2017",
"ViewCount": 1124
},
{
"Id": 2002,
"RowId": "518",
"Time": "Today, 07:02 PM",
"ViewCount": 62
},
{
"Id": 2002,
"RowId": "519",
"Time": "27 Jun 2017",
"ViewCount": 4833
},
{
"Id": 2041,
"RowId": "525",
"Time": "17 Feb 2015",
"ViewCount": 24491
}
],
"TotalUsers": 26,
"UsersDetails": "2 members, 1 anonymous users;4 members, 19 anonymous users"
}
Aggregate the data in a single iteration.
let ActiveMembers = [];
let Contents = [];
let TotalUsers = 0;
let UserDetails = [];
input.forEach((item) => {
ActiveMembers = ActiveMembers.concat(item.ActiveMembers);
Contents = Contents.concat(item.Contents);
TotalUsers += item.TotalUsers;
UserDetails.push(item.UsersDetails);
});
const result = {
ActiveMembers: _.uniqBy(ActiveMembers, "Id"),
Contents: Contents,
TotalUsers: TotalUsers,
UserDetails: UserDetails.join(";")
};
console.log(JSON.stringify(result));