Update:
I slightly tweaked the code in previous solution to make it run in linear time O(n) making it slightly faster by maintaining a "hashmap". For an array of given size in original question, performance enhancements will be zero, but its nonetheless faster solution.
// concat all items of all arrays into a big array
var bigArray = [].concat(array1, array2, array3);
// maintain a hashmap to track if "ref" exists at any index in any previous obj of array
// key=ref, value=index-where-ref-exists
var hash = {};
// loop over bigArray
for (var i = 0; i < bigArray.length; i++) {
// current obj we are processing
var currObj = bigArray[i];
// change price to number format
var priceInNumberFormat = parseFloat(currObj.price);
// if price is not a valid number, move onto processing next obj
if (!isNumber(priceInNumberFormat)) {
continue;
}
// update currentObj's "price" property. We need it to be in number format so we could do addition
currObj.price = priceInNumberFormat;
// check if any obj exits with same ref value.
if (hash[currObj.ref] !== undefined) {
var idx = hash[currObj.ref]; // index of existing obj with same "ref"
bigArray[idx].price += currObj.price;
bigArray.splice(i, 1);
// backtrack on "i" value since we shortened the length of the array
i--;
} else {
hash[currObj.ref] = i;
}
}
Previous Solution:
Here is one possible solution:
var array1 = [
{ price:"2", ref:"A" },
{ price:"20", ref:"B" },
{ price:"23", ref:"C" },
{ price:"23", ref:"D" }
];
var array2 = [
{ price:"12", ref:"A" },
{ price:"5", ref:"B" },
{ price:"23", ref:"E" },
{ price:"23", ref:"F" }
];
var array3 = [
{ name:"Blah", fcp:"erol" },
{ name:"Blah2", fcp:"tpep" }
];
// helper function to determine if a arg is valid number
function isNumber (num) {
return (typeof num === 'number' && !isNaN(num));
}
// concat all items of all arrays into a big array
var bigArray = [].concat(array1, array2, array3);
// loop over bigArray
for (var i = 0; i < bigArray.length; i++) {
// current obj we are processing
var currObj = bigArray[i];
// change price to number format
var iPriceInNumberFormat = parseFloat(currObj.price);
// if price is not a valid number, move onto processing next obj
if (!isNumber(iPriceInNumberFormat)) {
continue;
}
// update currentObj's "price" property. We need it to be in number format so we could do addition
currObj.price = iPriceInNumberFormat;
// now loop over remaining items of bigArray
for (var j = i+1; j < bigArray.length; j++) {
// if there is another object further down bigArray with same "ref" value as currObj
if (currObj.ref === bigArray[j].ref) {
// convert its price to number format as well
var jPriceInNumberFormat = parseFloat(bigArray[j].price);
// if its not a valid number, move onto next obj
if (!isNumber(jPriceInNumberFormat)) {
continue;
}
// otherwise add its price value to currObj's price
currObj.price += jPriceInNumberFormat;
// since we have added the price of this obj, discard it.
// remove bigArray[j] from bigArray
bigArray.splice(j, 1);
}
}
}
// now bigArray has removed all objects with duplicate "ref" values, and has their prices added
console.log(bigArray);
// should print bigArray value as expected solution:
// [ { price: 14, ref: 'A' },
// { price: 25, ref: 'B' },
// { price: 23, ref: 'C' },
// { price: 23, ref: 'D' },
// { price: 23, ref: 'E' },
// { price: 23, ref: 'F' },
// { name: 'Blah', fcp: 'erol' },
// { name: 'Blah2', fcp: 'tpep' } ]