Sorting and combining JSON keys with corresponding values
My JSON looks like this:
json = [
{
type: "big"
date: "2012-12-08"
qty: 6
}
{
type: "small"
date: "2012-12-08"
qty: 9
}
{
type: "big"
date: "2012-12-15"
qty: 4
}
{
type: "small"
date: "2012-12-07"
qty: 7
}
{
type: "small"
date: "2012-11-07"
qty: 3
}
]
What I am trying to do is group / merge each type
that has date
with the same year and month (first 7 characters in the line date
) and get the sum of these qty
's. The result should look like this:
json = [
{
type: "big"
date: "2012-12"
qty: 10
}
{
type: "small"
date: "2012-12"
qty: 16
}
{
type: "small"
date: "2012-11"
qty: 3
}
]
There are a couple of similar questions I've found here, but haven't come across one that does exactly what I'm looking for. I played around with a lot of code borrowed from various examples, but couldn't seem to get the results I wanted. I am not at home right now, so I cannot paste the code I have tried at the moment, but I ask for help in the hopes of getting an answer / solution to check later
source to share
This is easily handled by creating a custom object that has properties named with your unique combinations (i.e. type + first 7 dates).
Loop through the array and check if your "owner" object has an existing property with your unique identifier. If it already has the property, then increase the quantity, otherwise add a new element.
After the holder is fully constructed, clear the array, then loop through the holder properties and re-insert it into your array.
var holder = {};
var json = [
{
type: "big",
date: "2012-12-08",
qty: 6
},
{
type: "small",
date: "2012-12-08",
qty: 9
},
{
type: "big",
date: "2012-12-15",
qty: 4
},
{
type: "small",
date: "2012-12-07",
qty: 7
},
{
type: "small",
date: "2012-11-07",
qty: 3
}
];
json.forEach(function(element) {
var identifier = element.type + element.date.slice(0, 7);
if (holder[identifier]) {
holder[identifier].qty += element.qty;
} else {
holder[identifier] = element;
};
});
json = [];
for(var identifier in holder) {
json.push(holder[identifier]);
}
console.log(json);
source to share
Alternative solution:
var result = [];
$(json).each(function (i, e){
var search = $.grep(result, function(elm){ return e.type == elm.type && e.date.substring(0, 7) == elm.date; });
if(search.length == 0)
result.push({ type: e.type, date: e.date.substring(0, 7), qty: e.qty });
else
search[0].qty += e.qty;
});
source to share
Another one to confuse, which I think is the longest answer of all :-)
var sortedArray = [];
function traverseArray(element, index, array) {
var found = false;
for (i = 0; i < sortedArray.length; i++) {
if (sortedArray[i].type === element.type) {
if (sortedArray[i].date.substring(0, 7) === element.date.substring(0, 7)) {
sortedArray[i].qty = (sortedArray[i].qty + element.qty);
console.log(element);
found = true;
}
}
}
if (!found)
sortedArray.push(element);
}
var data = [{
type: "big",
date: "2012-12-08",
qty: 6
}, {
type: "small",
date: "2012-12-08",
qty: 9
}, {
type: "big",
date: "2012-12-15",
qty: 4
}, {
type: "small",
date: "2012-12-07",
qty: 7
}, {
type: "small",
date: "2012-11-07",
qty: 3
}];
data.forEach(traverseArray);
sortedArray.forEach(print);
function print(element, index, array) {
var line = "[ type: " + element.type + ", date: " + element.date + ", qty: " + element.qty + "]";
$("#result").append(line + " <br>");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"></div>
source to share