javascript sum array of arrays of objects together - javascript

i have an array with the following format
[
[{year:2015, value:23000, value1:1000},{year:2016,value:1000, value1:2000},{year:2017,value:400, value1:3000}],
[{year:2015, value:10000, value1:1000},{year:2016,value:2000, value1:3000},{year:2017,value:500, value1:2000}],
]
i want to sum them together, in this example, i want to have
[{year:2015,value:33000, value1:2000},{year:2016,value:3000, value1:5000},{year:2017,value:900, value1:5000}]
if there are only two arrays in the array but there maybe more arrays in the bigger array. how can i achieve this? currently, i am not able to figure out a good method. Thanks

Ecmascript5 solution:
var arr = [
[{year:2015, value:23000, value1:1000},{year:2016,value:1000, value1:2000},{year:2017,value:400, value1:3000}],
[{year:2015, value:10000, value1:1000},{year:2016,value:2000, value1:3000},{year:2017,value:500, value1:2000}]
],
// summing up values for each `year`
years = arr.reduce(function (r, a) {
a.forEach(function (o) {
y = o.year;
if (Array.isArray(r[y])) {
r[y][0] += o.value;
r[y][1] += o.value1;
} else {
r[y] = [o.value, o.value1];
}
});
return r;
}, {}),
// constructing the resulting array containing objects with `year` totals
result = Object.keys(years).map(function (y) {
return {year: y, value: years[y][0], value1: years[y][1]};
});
console.log(result);

You can loop over the items and add value agains a year number (key) in a map / object.
var data = [
[{year:2015, value:23000},{year:2016,value:1000},{year:2017,value:400}],
[{year:2015, value:10000},{year:2016,value:2000},{year:2017,value:500}],
];
var output = {};
data.forEach(function(item) {
item.forEach(function(obj) {
output[obj.year] = (output[obj.year] || 0) + obj.value;
});
});
output = [output]
console.log(output);
One way is to flat this 2D array first.
var output = {};
var flatArray = data.reduce(function(a, b) {
return a.concat(b);
}, []);
flatArray.forEach(function(obj) {
output[obj.year] = (output[obj.year] || 0) + obj.value;
});
output = [output]
console.log(output);
output: [{
2015: 33000,
2016: 3000,
2017: 900
}]

You could use a hash table for collecting a single year and a nested approach for the arrays with iterating all properties of the given objects.
Then create new properties and add the actual value.
It works with an arbitrary count of properties.
var data = [[{ year: 2015, value: 23000, value1: 1000 }, { year: 2016, value: 1000, value1: 2000 }, { year: 2017, value: 400, value1: 3000 }], [{ year: 2015, value: 10000, value1: 1000 }, { year: 2016, value: 2000, value1: 3000 }, { year: 2017, value: 500, value1: 2000 }]],
result = data.reduce(function (hash) {
return function (r, a) {
a.forEach(function (o) {
if (!hash[o.year]) {
hash[o.year] = { year: o.year };
r.push(hash[o.year]);
}
Object.keys(o).forEach(function (k) {
if (k !== 'year') {
hash[o.year][k] = (hash[o.year][k] || 0) + o[k];
}
});
});
return r;
};
}(Object.create(null)), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Here's a working solution. This will do what you're looking for. Hope it helps!
var arr = [
[{year:2015, value:23000, value1:1000},{year:2016,value:1000, value1:2000},{year:2017,value:400, value1:3000}],
[{year:2015, value:10000, value1:1000},{year:2016,value:2000, value1:3000},{year:2017,value:500, value1:2000}],
]
var result = [];
for(var i = 0; i < arr[0].length; i++){
var count = 0
var count2 = 0;
for(var j = 0; j < arr.length; j++){
var year = arr[j][i].year;
count += arr[j][i].value;
count2 += arr[j][i].value1;
}
result.push({
year: year,
value: count,
value1: count2
});
}
console.log(result);

Related

Issue arranging values in ascending order [duplicate]

This question already has answers here:
Sort Array Elements (string with numbers), natural sort
(8 answers)
Closed 11 months ago.
I am trying to arrange given values in ascending orders
const value = [
{ val: "11-1" },
{ val: "12-1b" },
{ val: "12-1a" },
{ val: "12-700" },
{ val: "12-7" },
{ val: "12-8" },
];
I am using code below to sort this in ascending order:
value.sort((a,b)=>(a.val >b.val)? 1:((b.val>a.val)?-1:0));
The result of this sort is in the order 11-1,12-1a, 12-1b, 12-7, 12-700, 12-8. However, I want the order to be 11-1,12-1a, 12-1b, 12-7, 12-8, 12-700.
How can I achieve that?
If you're only interested of sorting by the value after the hyphen you can achieve it with this code:
const value = [
{val:'12-1'},
{val:'12-700'},
{val:'12-7'},
{val:'12-8'},
];
const sorted = value.sort((a,b) => {
const anum = parseInt(a.val.split('-')[1]);
const bnum = parseInt(b.val.split('-')[1]);
return anum - bnum;
});
console.log(sorted);
updated the answer as your question update here's the solution for this:
const value = [{ val: '11-1' }, { val: '12-1b' }, { val: '12-1a' }, { val: '12-700' }, { val: '12-7' }, { val: '12-8' }];
const sortAlphaNum = (a, b) => a.val.localeCompare(b.val, 'en', { numeric: true });
console.log(value.sort(sortAlphaNum));
You can check the length first and then do the sorting as follow:
const value = [
{ val: "12-1" },
{ val: "12-700" },
{ val: "12-7" },
{ val: "12-8" },
];
const result = value.sort(
(a, b)=> {
if (a.val.length > b.val.length) {
return 1;
}
if (a.val.length < b.val.length) {
return -1;
}
return (a.val >b.val) ? 1 : ((b.val > a.val) ? -1 : 0)
}
);
console.log(result);
little change's to #Christian answer it will sort before and after - value
const value = [{ val: '12-1' }, { val: '12-700' }, { val: '11-7' }, { val: '12-8' }];
const sorted = value.sort((a, b) => {
const anum = parseInt(a.val.replace('-', '.'));
const bnum = parseInt(b.val.replace('-', '.'));
return anum - bnum;
});
console.log(sorted);
If you want to check for different values both before and after the hyphen and include checking for letters, the solution at the end will solve this.
Here's what I did:
Created a regex to split the characters by type:
var regexValueSplit = /(\d+)([a-z]+)?-(\d+)([a-z]+)?/gi;
Created a comparison function to take numbers and letters into account:
function compareTypes(alpha, bravo) {
if (!isNaN(alpha) && !isNaN(bravo)) {
return parseInt(alpha) - parseInt(bravo);
}
return alpha > bravo;
}
Split the values based on regexValueSplit:
value.sort((a, b) => {
let valuesA = a.val.split(regexValueSplit);
let valuesB = b.val.split(regexValueSplit);
This produces results as follows (example string "12-1a"):
[
"",
"12",
null,
"1",
"a",
""
]
Then, since all the split arrays should have the same length, compare each value in a for loop:
for (let i = 0; i < valuesA.length; i++) {
if (valuesA[i] !== valuesB[i]) {
return compareTypes(valuesA[i], valuesB[i]);
}
}
// Return 0 if all values are equal
return 0;
const value = [{
val: "11-1"
},
{
val: "12-1b"
},
{
val: "12-1a"
},
{
val: "12-700"
},
{
val: "12-7"
},
{
val: "12-8"
},
];
var regexValueSplit = /(\d+)([a-z]+)?-(\d+)([a-z]+)?/gi;
function compareTypes(alpha, bravo) {
if (!isNaN(alpha) && !isNaN(bravo)) {
return parseInt(alpha) - parseInt(bravo);
}
return alpha > bravo;
}
value.sort((a, b) => {
let valuesA = a.val.split(regexValueSplit);
let valuesB = b.val.split(regexValueSplit);
for (let i = 0; i < valuesA.length; i++) {
if (valuesA[i] !== valuesB[i]) {
return compareTypes(valuesA[i], valuesB[i]);
}
}
return 0;
});
console.log(JSON.stringify(value, null, 2));
Since you are sorting on string values, try using String.localeCompare for the sorting.
Try sorting on both numeric components of the string.
const arr = [
{val:'12-1'},
{val:'11-900'},
{val:'12-700'},
{val:'12-7'},
{val:'11-1'},
{val:'12-8'},
{val:'11-90'},
];
const sorter = (a, b) => {
const [a1, a2, b1, b2] = (a.val.split(`-`)
.concat(b.val.split(`-`))).map(Number);
return a1 - b1 || a2 - b2; };
console.log(`Unsorted values:\n${
JSON.stringify(arr.map(v => v.val))}`);
console.log(`Sorted values:\n${
JSON.stringify(arr.sort(sorter).map(v => v.val))}`);

How to convert an unorganized array into an grouped array by id

I'm trying to create an array that contains objects with an id and amount, grouped by id. The ids needs to be unique. So if there is 2 objects with same id, the amount will be added.
I can do it with nested for-loops, but I find this solution inelegant and huge. Is there a more efficient or cleaner way of doing it?
var bigArray = [];
// big Array has is the source, it has all the objects
// let's give it 4 sample objects
var object1 = {
id: 1,
amount: 50
}
var object2 = {
id: 2,
amount: 50
}
var object3 = {
id: 1,
amount: 150
}
var object4 = {
id: 2,
amount:100
}
bigArray.push(object1,object2,object3,object4);
// organizedArray is the array that has unique ids with added sum. this is what I'm trying to get
var organizedArray = [];
organizedArray.push(object1);
for(var i = 1; i < bigArray.length; i++ ) {
// a boolean to keep track whether the object was added
var added = false;
for (var j = 0; j < organizedArray.length; j++){
if (organizedArray[j].id === bigArray[i].id) {
organizedArray[j].amount += bigArray[i].amount;
added = true;
}
}
if (!added){
// it has object with new id, push it to the array
organizedArray.push(bigArray[i]);
}
}
console.log(organizedArray);
You can definitly make it cleaner and shorter by using reduce, not sure about efficiency though, i would say a traditional for loop is more efficient :
var bigArray = [];
var object1 = {id: 1, amount: 50}
var object2 = {id: 2, amount: 50}
var object3 = {id: 1, amount: 150}
var object4 = {id: 2, amount: 100}
bigArray.push(object1, object2, object3, object4);
var organizedArray = bigArray.reduce((acc, curr) => {
// check if the object is in the accumulator
const ndx = acc.findIndex(e => e.id === curr.id);
if(ndx > -1) // add the amount if it exists
acc[ndx].amount += curr.amount;
else // push the object to the array if doesn't
acc.push(curr);
return acc;
}, []);
console.log(organizedArray)
Rather than an organized array, how about a single object whose keys are the ids and values are the sums.
var bigArray = [
{ id: 1, amount: 50 },
{ id: 2, amount: 50 },
{ id: 1, amount: 150 },
{ id: 2, amount: 100 }
];
let total = {}
bigArray.forEach(obj => {
total[obj.id] = (total[obj.id] || 0) + obj.amount;
});
console.log(total);
If you really need to convert this to an array of objects then you can map the keys to objects of your choosing like this:
var bigArray = [
{ id: 1, amount: 50 },
{ id: 2, amount: 50 },
{ id: 1, amount: 150 },
{ id: 2, amount: 100 }
];
let total = {}
bigArray.forEach(obj => {
total[obj.id] = (total[obj.id] || 0) + obj.amount;
});
console.log(total);
// If you need the organized array:
let organizedArray = Object.keys(total).map(key => ({ id: key, amount: total[key] }));
console.log(organizedArray);
function getUniqueSums(array) {
const uniqueElements = [];
const arrayLength = array.length;
for(let index = 0; index < arrayLength; index++) {
const element = array[index];
const id = element.id;
const uniqueElement = findElementByPropertyValue(uniqueElements, 'id', id);
if (uniqueElement !== null) {
uniqueElement.amount += element.amount;
continue;
}
uniqueElements.push(element);
}
return uniqueElements;
}
function findElementByPropertyValue(array, property, expectedValue) {
const arrayLength = array.length;
for(let index = 0; index < arrayLength; index++) {
const element = array[index];
const value = element[property];
if (value !== expectedValue) {
continue;
}
return element;
}
return null;
}
This is an untested code. You will be able to understand the logic. Logic is almost same yours. But, perhaps a more readable code.

JavaScript: Compare dates in an array and sum the "price" for each month/year

I have a json file with multiple transactions with a date and a price attribute. Now I want to compare the dates and if they are in the same month and year I want to sum up the prices.
JSON:
transactions: [
{
date: "2017-11-17",
price: "28",
},
{
...
}
JavaScript:
request.onload = function() {
for(const transaction of request.response.transactions) {
let year = new Date(transaction.date).getFullYear();
let month = new Date(transaction.date).getMonth();
console.log(year + ' ' + month); // output: 2017-11 ...
}
};
I tried to loop over the json object but I struggle to find a solution to compare the dates.
Edit: Edited example with Object.assign instead of Object spread.
You'll need to use reduce to sum the prices. See comments for details.
const transactions = [{
date: "2017-11-17",
price: "28",
},
{
date: "2017-12-17",
price: "23",
},
{
date: "2017-11-17",
price: "12",
},
{
date: "2017-10-17",
price: "55",
},
{
date: "2017-11-17",
price: "09",
},
];
const sumTransactions = (transactions) => {
const summed = transactions.reduce((acc, current) => {
// Get the current date object
const date = new Date(current.date);
// Create your key/identifier
const key = `${date.getFullYear()}-${date.getMonth() + 1}`;
// Retreive the previous price from the accumulator
const previousPrice = acc[key]; // Might also return undefined
// Create your temp current price value, and be sure to deal with numbers.
let currentPrice = Number(current.price);
// If you had a previous value (and not undefined)
if (previousPrice) {
// Add it to our value
currentPrice += Number(previousPrice);
}
// Return the future accumulator value
return Object.assign(acc, {
[key]: currentPrice, // new values will overwrite same old values
})
}, {})
// Once we have all values, get the dates, and sort them (default: earlier first)
// Return an array of each value from the summed object to our sortedArray
const sortedArray = Object.keys(summed).sort().map((val) => {
return summed[val];
});
console.log("sortedArray", sortedArray);
};
sumTransactions(transactions);
I experimented a bit and came up with this solution:
var transactions = [
{
date: "2017-11-17",
price: "28",
},
{
date: "2017-12-17",
price: "22",
},
{
date: "2017-12-17",
price: "20",
}
]
var sumedUpDates = [];
var prices = [];
function isDateSumedUp(date) {
return sumedUpDates.indexOf(date.substring(0, 7)) !== -1;
}
function sumUpDate(date) {
var sum = 0;
transactions.forEach(t => {
if(t.date.substring(0, 7) === date.substring(0, 7)) {
sum += parseInt(t.price);
}
});
sumedUpDates.push(date.substring(0, 7));
prices.push(sum);
}
transactions.forEach(t => {
if(!isDateSumedUp(t.date)) {
sumUpDate(t.date);
}
});
var obj = {};
sumedUpDates.forEach((d, i) => obj[d] = prices[i]);
console.log(obj);
This solutions uses map to format your dates into year/month format for each object entry and then reduce to sum them by those separated dates.
const transactions = [
{date:"2017-11-17", price: "28",},
{date:"2017-12-17", price: "28",},
{date:"2017-11-17", price: "20",},
{date:"2017-12-17", price: "2",},
{date:"2017-11-17", price: "58",},
{date:"2017-11-17", price: "8",},
{date:"2017-10-17", price: "30",},
{date:"2018-11-17", price: "1",},
];
const mapper = single => {
let d = single.date.split('-');
let p = Number(single.price);
return { year: d[0], month: d[1], price: p };
}
const reducer = (group, current) => {
let i = group.findIndex(single => (single.year == current.year && single.month == current.month));
if (i == -1) {
return [ ...group, current ];
}
group[i].price += current.price;
return group;
};
const sumPrices = transactions.map(mapper).reduce(reducer, []);
console.log(sumPrices);
var array = [];
for (var i = 0; i < transactions.length; i++) {
var date = new Date(transactions[i].date);
var ym = date.getFullYear() + "-" + date.getMonth();
if (array[ym] == null) {
array[ym] = 0;
}
array[ym] += parseInt(transactions[i].price);
}
With this data
var transactions = [{
date: "2017-11-17",
price: "28",
},
{
date: "2017-12-17",
price: "5",
},
{
date: "2016-02-17",
price: "28",
},
{
date: "2015-11-17",
price: "25",
},
{
date: "2016-02-17",
price: "12",
},
{
date: "2017-11-17",
price: "50",
}
];
This will give you the sum of all of the year-months duplicates like this :
[
2017-10: 78,
2017-11: 5,
2016-1: 40,
2015-10: 25
]
Another solution is reduce:
var transactions = [
{date: "2017-11-17",price: "28"},
{date: "2017-12-17",price: "22"},
{date: "2017-12-17",price: "20"}
];
var result = transactions.reduce(function(acc, obj) {
var key = obj.date.substr(0,7);
acc[key] = (acc[key] || 0) + +obj.price;
return acc;
}, Object.create(null));
console.log(result);

How to sort a JavaScript array by more nested objects in arrays and grab the top ###?

Here is a dummy example. I have an array of objects:
var cars = [
{
name: "Hyundai",
plans: [
{
name: "Something",
add-ons: [
{
cost: 100
},
{
cost: 75
}
]
}, { ... }
]
},
{
name: "Jeep",
plans: [
{
name: "Something",
add-ons: [
{
cost: 50
},
{
cost: 75
}
]
}, { ... }
]
},
{
name: "Buick",
plans: [
{
name: "Something",
add-ons: [
{
cost: 35
},
{
cost: 50
}
]
}, {...}
]
}
]
What I'm trying to do is find the top 2 cars that have the cheapest add-on and reference them via another variable.
Like this:
var top2 = findTopTwo(cars);
findTopTwo(arr) {
return arr.sort(function(a, b) {
// My trouble spot
}).slice(0, 2);
}
With my simple example, the result for top2 would be:
Buick ( cheapest add-on was $35, the value used to compare against )
Jeep ( cheapest add-on was $50, value used to compare against )
So what I would do is feed all of them into an array and then sort it on the cost. That would be my naive approach. The more optimal solution would be to only store 2 objects at a given time instead of a list of all items.
The naive approach would be as simple as:
var items = [];
for ( var i in cars ){
var car = cars[i];
for (var i in car["plans"]){
for (var j = 0; j < car["plans"][i]["add-ons"]){
items.push({"name": car.name, "cost": car["plans"][i]["add-ons"][j]["cost"]});
}
}
}
return items.sort(function(a,b){ return a.cost < b.cost }).slice(0,2);
That will return a list of 2 objects, the object contains the name of the car and the cost. The more effecient thing would be to do something like this:
var biggest = function(arr){
if (arr.length < 2 ) return -1;
return arr[0].cost > arr[1].cost ? 0 : 1;
}
var items = [];
for ( var i in cars ){
var car = cars[i];
for (var i in car["plans"]){
for (var j = 0; j < car["plans"][i]["add-ons"]){
var obj = {"name": car.name, "cost": car["plans"][i]["add-ons"][j]["cost"]};
}
var index = biggest(items)
if (index < 0){
items.push(obj);
}else{
if (items[index].cost > obj.cost)
items[index] = obj;
}
}
}
return items;
this more interesting design will push the first 2 into the list, but then it will find the biggest of the 2 costs and then checks to see if the new one is smaller than it. If the new one is smaller than item[index] it will be replaced.
This will never have the array larger than 2 so it takes up less memory
Another approach. By this approach your original data will not be sorted or modified.
var cars=[{name:"Hyundai",plans:[{name:"Something","add-ons":[{cost:100},{cost:75}]}]},
{name:"Jeep",plans:[{name:"Something","add-ons":[{cost:50},{cost:75}]}]},
{name:"Buick",plans:[{name:"Something","add-ons":[{cost:35},{cost:50}]}]}];
function findTopTwo(cars) {
return cars.map(
car =>
car.plans.reduce(
(prevPlan, plan) =>
plan['add-ons'].reduce((prevAddOn, addOn) => {
if (prevAddOn.cost > addOn.cost) {
prevAddOn.cost = addOn.cost;
}
return prevAddOn;
}, prevPlan), {
cost: Number.MAX_VALUE,
name: car.name
})
)
.sort((a, b) => a.cost - b.cost)
.slice(0, 2)
.map(item => item.name);
}
console.log(findTopTwo(cars));
I had to play around with the object, but here is the gist of it -
var cars = [{
name: "Hyundai",
plans: {
addons: [{
cost: 100
}, {
cost: 75
}]
}
}, {
name: "Jeep",
plans: {
addons: [{
cost: 50
}, {
cost: 75
}]
}
}, {
name: "Buick",
plans: {
addons: [{
cost: 35
}, {
cost: 50
}]
}
}];
var top2 = findTopTwo(cars);
console.log(top2);
function findTopTwo(arr) {
return arr.sort(function (a, b) {
// this map outputs array of costs: [35, 40]
// and Math.min takes the lowest value of each
var a_max_cost = Math.min.apply(null, a.plans.addons.map(function(i){i.cost})),
b_max_cost = Math.min.apply(null, b.plans.addons.map(function(i){i.cost}));
return a_max_cost - b_max_cost;
})
.slice(0, 2);
}
Basically, you need to return a-b in the sort function, where a and b are the lowest addon values. So I calculated the max of both cars on comparison, and used those values to decide which goes where.
Edit: I see you've updated the JS object, the answer should be similar to min, you will only need to figure out which plan to use for a and b. You can do so similar to my use of the Math.max function
One simple way of doing it is to first sort the addons by price (if you don't mind the side effect that addons then remain sorted by price).
function findTopTwo(arr) {
arr.forEach(function (elem) {
elem.plans.addons = elem.plans.addons.sort(function (a, b) {
return a.cost > b.cost;
});
});
return arr.sort(function(a, b) {
return a.plans.addons[0].cost > b.plans.addons[0].cost;
}).slice(0, 2);
}
jsbin example
Using #casraf's data:
const sortedCars = cars.map(car => {
car.plans.addons.sort((a, b) => a.cost - b.cost);
return car;
}).sort((a, b) => {
return a.plans.addons[0].cost - b.plans.addons[0].cost;
});
Line 2 sorts each cars' addons array from low to high. Line 5 sorts the cars from low to high based on the first index of their respective addons property.
If the ES6 syntax is confusing, here's a translation to ES5
I suggest to use sorting with map, then take the top 2 entries and get the data from cars.
var cars = [{ name: "Hyundai", plans: [{ 'add-ons': [{ cost: 100 }, { cost: 75 }] }] }, { name: "Jeep", plans: [{ 'add-ons': [{ cost: 50 }, { cost: 75 }] }] }, { name: "Buick", plans: [{ 'add-ons': [{ cost: 35 }, { cost: 50 }] }] }],
cost = cars.
map(function (a, i) {
return {
index: i,
cost: a.plans.reduce(function (r, b) {
return Math.min(r, b['add-ons'].reduce(function (s, c) {
return Math.min(s, c.cost);
}, Infinity));
}, Infinity)
};
}).
sort(function (a, b) { return a.cost - b.cost; }),
top2 = cost.slice(0, 2).map(function (a) {
return cars[a.index];
});
console.log(top2);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Get Maximum value from JSON object using javascript?

I have JSON like
var JObject = [
{
a:"A1",
b:100,
c:800
},
{
a:"B1",
b:300,
c:400
}
];
I need maximum value from this JSON...it has to return 800 if it return key and column index
Since this is tagged in d3.
I will give a d3 answer.
Working code below
var kary = [
{
a:"A1",
b:100,
c:800
},
{
a:"B1",
b:1300,
c:400
},
{
a:"D1",
b:300,
c:400
}
];
var max = d3.max(kary, function(d){ return d3.max(d3.values(d).filter(function(d1){ return !isNaN(d1)}))});
console.log(max)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Hope this helps!
You can do something like this
var JObject = [{
a: "A1",
b: 100,
c: 800
}, {
a: "B1",
b: 300,
c: 400
}];
var res = Math.max.apply(null,JObject.map(function(v) {
// iterate over array element and getting max value from result array
var r = [];
for (var val in v) {
// iterate over object inside array
if (v.hasOwnProperty(val)) {
var num = parseInt(v[val], 10);
// parsing the value for integer output
r.push(isNaN(num) ? 0 : num);
// pushing value to array, in case of `Nan` pushing it as 0
}
}
return Math.max.apply(null,r);
// getting max value from object values
}));
console.log(res);
You could make this more or less generic - and probably shorten it into a single reduce statement.
var data = [
{a:"A1",b:100,c:800},
{a:"B1",b:300,c:400}
];
data
.reduce(function(acc, x, i) {
if (x.b > x.c) {
return acc.concat({key: 'b', value: x.b });
}
return acc.concat({key: 'c', value: x.c });
}, [])
.reduce(function(acc, x, i) {
if (x.value > acc.value) {
return {
key: x.key,
value: x.value,
index: i
};
}
return acc;
}, {key: '', value: Number.MIN_VALUE, index: -1});
If you are using a library like lodash or underscore you can simply do:
_.max(_.map(JObject, function(a){
return _.max(_.values(a));
}));
You can also solve it with reduce:
_.reduce(JObject, function(val, a){
return _.max(_.values(a)) > val ? _.max(_.values(a)) : val;
},0);

Categories