Reputation: 10401
I have some javascript that is fetching some JSON and I'm trying to combine certain rows of information together to use in a table.
The JSON looks like below:
[{"Code":"12345","Name":"foo","Service":"Payments"},
{"Code":"12345","Name":"foo","Service":"Marketing"},
{"Code":"23456","Name":"bar","Service":"Payments"},
{"Code":"23456","Name":"bar","Service":"Development"},
{"Code":"34567","Name":"baz","Service":"Marketing"}]
Basically some rows share the exact same information with each other except for one field, Service
.
My thought was to try to turn each row into an object that I can either update or merge with another object that shares the same Code
.
That object and code looks something like this:
function CustObj(code,name,hasPay,hasMarket,hasDev) {
this.code = code;
this.name = name;
this.hasPay = hasPay;
this.hasMarket = hasMarket;
this.hasDev = hasDev;
}
function formatData(data) {
var formatedData = [];
for (var key in data) {
var customer = new CustObj(data[key].Code,data[key].Name);
switch (data[key].Service) {
case 'Payments':
customer.hasPay = true;
break;
case 'Marketing':
customer.hasMarket = true;
break;
case 'Development':
customer.hasDev = true;
break;
}
formatedData.push(school);
}
}
The problem is that I want to have one object for each unique Code
but that has the correct amount of flags based on Service
but I haven't figured out how to do that yet. I was looking at doing something like $.extend(formatedData,customer)
to merge objects but I can't seem to get the right logic for locating the two objects that I'm trying to merge.
Any thoughts on how this can be accomplished?
Upvotes: 1
Views: 73
Reputation: 707178
You can process the array for duplicates and create a new array where the "Service" property is an array of services that share the same Code
and Name
:
var data = [
{"Code":"12345","Name":"foo","Service":"Payments"},
{"Code":"12345","Name":"foo","Service":"Marketing"},
{"Code":"23456","Name":"bar","Service":"Payments"},
{"Code":"23456","Name":"bar","Service":"Development"},
{"Code":"34567","Name":"baz","Service":"Marketing"}
];
function mergeServices(data) {
var result = [], item, match, found;
// for each array item
for (var i = 0; i < data.length; i++) {
item = data[i];
found = false;
for (var j = 0; j < result.length; j++) {
// see if we have a dup of a previously existing item
if (item.Code == result[j].Code && item.Name == result[j].Name) {
// just add the Service name to the array of the previous item
result[j].Service.push(item.Service);
found = true;
break;
}
}
if (!found) {
// copy the current row (so we can change it without changing original)
var newItem = {};
for (var prop in item) {
newItem[prop] = item[prop];
}
// convert service to an array
newItem.Service = [newItem.Service];
result.push(newItem);
}
}
return result;
}
var output = mergeServices(data);
That produces this output
:
[
{"Code":"12345","Name":"foo","Service":["Payments","Marketing"]},
{"Code":"23456","Name":"bar","Service":["Payments","Development"]},
{"Code":"34567","Name":"baz","Service":["Marketing"]}
]
Working jsFiddle: http://jsfiddle.net/jfriend00/6rU2z/
Upvotes: 2
Reputation: 5958
As you create your customers you can add them to a map (an object) so that they can be referenced by code. You only create customers that are not already in the map. For each row you get or create the corresponding customer and set the corresponding flag.
function formatData(data) {
var customerMap = {};
$(data).each(function(index, elem){
// Get the customer if it is already in the map, else create it
var customer = customerMap[elem.Code];
if(!customer) {
customer = new CustObj(elem.Code, elem.Name);
customerMap[elem.Code] = customer;
}
// Add flags as appropiate
switch (elem.Service) {
case 'Payments':
customer.hasPay = true;
break;
case 'Marketing':
customer.hasMarket = true;
break;
case 'Development':
customer.hasDev = true;
break;
}
});
// Convert map to array
var formatedData = [];
for(var code in customerMap){
formatedData.push(customerMap[code]);
}
}
function CustObj(code,name) {
this.code = code;
this.name = name;
this.hasPay = false;
this.hasMarket = false;
this.hasDev = false;
}
EDIT I've created a fiddle to demonstrate this
Upvotes: 2