-1

I have the following list (object):

var data = [{
    id: 1,
    type: 'smartphone',
    details: [{
      brand: 'Samsung',
      model: 'Galaxy A5'
    }]
  },
  {
    id: 2,
    type: 'smartphone',
    details: [{
      brand: 'iPhone',
      model: '6 plus'
    }]
  },
  {
    id: 3,
    type: 'smartphone',
    details: [{
      brand: 'Samsung',
      model: 'Galaxy A5'
    }]
  },
  {
    id: 4,
    type: 'smartphone',
    details: [{
      brand: 'iPhone',
      model: '7 plus'
    }]
  },
  {
    id: 5,
    type: 'phone',
    details: [{
      brand: 'Nokia',
      model: '3310'
    }]
  },
  {
    id: 6,
    type: 'smartphone',
    details: [{
      brand: 'Samsung',
      model: 'Galaxy A5'
    }]
  },
  {
    id: 7,
    type: 'smartphone',
    details: [{
      brand: 'iPhone',
      model: '6 plus'
    }]
  }
]

I try to show on the page a filtered list of phones and with the total amount of them using javascript/ angular

So on my page I want the following result:

Phone: Samsung, Model: Galaxy A5, Total: 3

Phone: iPhone, Model: 7 plus, Total: 1

Phone: iPhone, Model: 6 plus, Total: 2

Phone: Nokia, Model: 3310, Total: 1

I will render it using ngFor but not quite sure how to filter and count total of each model at the same time. Thanks in advance!

SED
  • 110
  • 1
  • 8
  • I think that the answer is here: https://stackoverflow.com/questions/40774697/how-to-group-an-array-of-objects-by-key Cheers! – cbadillac May 31 '18 at 12:41

2 Answers2

2

You can use reduce() method to transform your data to one object or array of objects and also calculate total for each model and brand.

var data = [{"id":1,"type":"smartphone","details":[{"brand":"Samsung","model":"Galaxy A5"}]},{"id":2,"type":"smartphone","details":[{"brand":"iPhone","model":"6 plus"}]},{"id":3,"type":"smartphone","details":[{"brand":"Samsung","model":"Galaxy A5"}]},{"id":4,"type":"smartphone","details":[{"brand":"iPhone","model":"7 plus"}]},{"id":5,"type":"phone","details":[{"brand":"Nokia","model":"3310"}]},{"id":6,"type":"smartphone","details":[{"brand":"Samsung","model":"Galaxy A5"}]},{"id":7,"type":"smartphone","details":[{"brand":"iPhone","model":"6 plus"}]}]

var result = data.reduce((r, {details}) => {
  details.forEach(({brand, model}) => {
    let key = `${brand}|${model}`;
    if(!r[key]) r[key] = {phone: brand, model, total: 0}
    r[key].total++;
  })
  return r;
}, {})

console.log(Object.values(result))
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
1

You can use reduce to remove the duplicates..

var data = [{
    id: 1,
    type: 'smartphone',
    details: [{
      brand: 'Samsung',
      model: 'Galaxy A5'
    }]
  },
  {
    id: 2,
    type: 'smartphone',
    details: [{
      brand: 'iPhone',
      model: '6 plus'
    }]
  },
  {
    id: 3,
    type: 'smartphone',
    details: [{
      brand: 'Samsung',
      model: 'Galaxy A5'
    }]
  },
  {
    id: 4,
    type: 'smartphone',
    details: [{
      brand: 'iPhone',
      model: '7 plus'
    }]
  },
  {
    id: 5,
    type: 'phone',
    details: [{
      brand: 'Nokia',
      model: '3310'
    }]
  },
  {
    id: 6,
    type: 'smartphone',
    details: [{
      brand: 'Samsung',
      model: 'Galaxy A5'
    }]
  },
  {
    id: 7,
    type: 'smartphone',
    details: [{
      brand: 'iPhone',
      model: '6 plus'
    }]
  }
]

var reduced = data.reduce((acc, eachElem) => {
    var foundIndex = acc.findIndex((e) => {
      return eachElem.type == e.type && eachElem.details[0].brand == e.details[0].brand && eachElem.details[0].model == e.details[0].model;
    });
    if (foundIndex === -1) {
      eachElem["count"] = 1;
      acc.push(eachElem);
    }
    else {
      acc[foundIndex]['count']++
    }
    return acc;
}, [])

console.log(reduced);
Ashish Ranjan
  • 12,760
  • 5
  • 27
  • 51