2

I have multiple arrays, which looks like this

1st array of object looks like this

Array[4]

    0 : Object
        price:"2"       
        ref:"A"
    1 : Object
        price:"20"
        ref:"B"
    2 : Object
        price:"23"      
        ref:"C"
    3 : Object
        price:"23"      
        ref:"D"     

2nd array of objects looks like this

Array[4]

    0 : Object
        price:"12"      
        ref:"A"
    1 : Object
        price:"5"       
        ref:"B"
    2 : Object
        price:"23"      
        ref:"E"
    3 : Object
        price:"23"      
        ref:"F" 

And my third object looks like this.

Array[2]

0 : Object
    name:"Blah"     
    fcp:"erol"
1 : Object
    name:"Blah2"        
    fcp:"tpep"

Now i want to sum the price based on ref. 1st object and 2nd object has ref A and B common. So that the final object looks like

Array[7]

    0 : Object
        price:"14"      
        ref:"A"
    1 : Object
        price:"25"
        ref:"B"
    2 : Object
        price:"23"      
        ref:"C"
    3 : Object
        price:"23"      
        ref:"D" 
    4 : Object
        price:"23"      
        ref:"E"
    5 : Object
        price:"23"      
        ref:"F" 
    6 : Object
        name:"Blah"     
        fcp:"erol"
    7 : Object
        name:"Blah2"        
        fcp:"tpep"  
3
  • can you please share the arrays. I guess you took it from the console. Commented Mar 21, 2017 at 5:41
  • The array of object contains price and ref.. and last object contains name and fcp.. thats it Commented Mar 21, 2017 at 5:42
  • 1
    If I want to create a working copy , I have to take all the arrays and manually remove 0,1... & object word from each of the array, which is not only tedious but also time consuming. I am am expecting an array with original format, so that I can quickly create a working copy. Thank you Commented Mar 21, 2017 at 5:44

2 Answers 2

5

You can use reduce function for groupping

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"
  }
];

var result = array1.concat(array2, array3).reduce(function(acc, curr) {
  if (curr.ref) {
    var fromMap = acc.map[curr.ref];
    if (!fromMap) {
      acc.map[curr.ref] = fromMap = {
        price: 0,
        ref: curr.ref
      }
      acc.result.push(fromMap);
    }
    fromMap.price += parseFloat(curr.price);
  } else {
    acc.result.push(curr);
  }
  return acc;
}, {
  map: {},
  result: []
}).result;

console.log(result);

Sign up to request clarification or add additional context in comments.

Comments

0

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' } ]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.