-4

I have list01 like :

var list01 = [
   {
      date: **01/01/2015**,
      statut: [1,2,6],
      name: '**Name X**'
   },
   {
      date: **01/01/2015**,
      statut: [5,6],
      name: '**Name X**'
   },
   {
      date: 01/01/2016,
      statut: [5,6],
      name: 'Name Y'
   },
   ...
]

I want to generate list02 who contains all items that have the same name and date from list01

var list02 = [
   {
      date: 01/01/2015,
      name: 'Name x',
      **nbrItem: 2**
   },
   {
      date: 01/01/2016,
      statut: [5,6],
      name: 'Name Y',
      **nbrItem: 1**
   },
   ...
]

I want a better way to solve this problem

Karim Oukara
  • 2,638
  • 8
  • 38
  • 51
  • 6
    "a better way to solve this problem"... better than what? What are doing currently? – James Allardice Mar 04 '15 at 15:36
  • If you're looking to **clone** your object, [**this**](http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-an-object#answer-122190) might help you. – blex Mar 04 '15 at 15:38
  • Also, define "better" - faster performing? Easier to read? – James Thorpe Mar 04 '15 at 15:38
  • 1
    [`list02 = list01.map(yourfunctioncode)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map). – zzzzBov Mar 04 '15 at 15:38

2 Answers2

2

Please see if this fiddle does what you want. The basic idea is to create an empty list at the start, then loop through the original list. For each item in the original list, see if a matching item is already in your new list. If so, increment the nbrItem property. Otherwise, create a new object. The guts of the linked fiddle are shown below:

var len = list01.length;
var list02 = [];
for (var i = 0; i < len; i++) {
    var foundMatch = false;
    var len2 = list02.length;
    for (var j = 0; j < len2; j++) {
        if (list02[j].date == list01[i].date && list02[j].name == list01[i].name) {
            foundMatch = true;
            list02[j].nbrItem++;
            break;
        }
    }

    if (!foundMatch) {
        list02.push( {
            date: list01[i].date,
            name: list01[i].name,
            nbrItem: 1
        });
    }
}

Array.prototype.map turned out not to be a good fit in this case because you want an output with different lengths than the input. The method shown here just uses plain old for loops, which work in all browsers, even the really old ones that don't have map.

Austin Mullins
  • 7,307
  • 2
  • 33
  • 48
2

Edited:

var list02 = [];
list01.forEach(function(item) {
  var matched = list02.filter(function(filterItem) {
    return filterItem.name==item.name && filterItem.date==item.date
  })
  if(matched.length)
    matched[0].nbrItem++
  else
    list02.push({
      date: item.date, 
      name: item.name, 
      nbrItem: 1
    });
});