Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Saturday, August 20, 2016

Group values on same property

Group values on same property


I have an array like this:

[      {unit: 35, brand: 'CENTURY'},      {unit: 35, brand: 'BADGER'},      {unit: 25, brand: 'CENTURY'},      {unit: 15, brand: 'CENTURY'},      {unit: 25, brand: 'XEGAR'}  ]  

What I want is to mix the jsons with same unit value, joining the brands comma separated, so that the result array would be:

[      {unit: 35, brand: 'CENTURY, BADGER'},      {unit: 25, brand: 'CENTURY, XEGAR'},      {unit: 15, brand: 'CENTURY'}  ]  

Someone suggest me to use filter(), I'm reading about it at MDN, and something that I don't understand is how could I use the last invoked argument:

callback is invoked with three arguments:

  1. the value of the element
  2. the index of the element
  3. the Array object being traversed

I mean, I know it is the complete array, but if I'm already filtering it, how would that help me?

vm.products.filter(      function(product, index, products){          //How do I compare here if product === any product in products          //and then add mix them up?      }  )  

Answer by Pranav C Balan for Group values on same property


Iterate over the elements and generate new array

var arr = [{      unit: 35,      brand: 'CENTURY'    }, {      unit: 35,      brand: 'BADGER'    }, {      unit: 25,      brand: 'CENTURY'    }, {      unit: 15,      brand: 'CENTURY'    }, {      unit: 25,      brand: 'XEGAR'    }],    ind = [],    res = [];    // iterate over the array using forEach or for loop  arr.forEach(function(v) {    // checking unit value is in `ind` array      var eleIn = ind.indexOf(v.unit);    if (eleIn === -1) {      // pushing unit value to `ind` array      ind.push(v.unit);      // pushing array element to `res` array      res.push(v);    } else      // else case updating brand value      res[eleIn].brand += ', ' + v.brand;  })    document.write('
' + JSON.stringify(res, null, 3) + '
');

Answer by gurvinder372 for Group values on same property


try this

var objArray = [      {unit: 35, brand: 'CENTURY'},      {unit: 35, brand: 'BADGER'},      {unit: 25, brand: 'CENTURY'},      {unit: 15, brand: 'CENTURY'},      {unit: 25, brand: 'XEGAR'}  ];        var output = {};      var outputArr = [];      for( var counter = 0; counter < objArray.length; counter++ )      {         var unit = objArray[ counter ].unit;         if ( !output [ unit ] )         {            output [ unit ] = [];         }         output [ unit ].push( objArray[ counter ].brand );      }       for ( var unit in output )      {        outputArr.push( { unit: unit, brand: output[ unit ].join( "," ) } );      }     console.log( outputArr );  

Answer by JosephGarrone for Group values on same property


I came up with a somewhat generic solution at this fiddle.

What is does is take a field to group the data on. When it finds a match, it then modifies the first object that had that field and adds all the properties on the other instances that match that field to it. IE: If you were to add extra fields on a unit 35 instance below, they would be copied to the combined instance. This can be turned off by commenting out the inner most else statement.

Here is the code

var data = [      {unit: 35, brand: 'CENTURY'},      {unit: 35, brand: 'BADGER'},      {unit: 25, brand: 'CENTURY'},      {unit: 15, brand: 'CENTURY'},      {unit: 25, brand: 'XEGAR'}  ];    function groupBy(field, data) {    var result = [];    var ignore = [];      for (var i = 0; i < data.length; i++) {      var current = data[i];      var isNew = true;        // Find matching elements      for (var j = 0; j < data.length; j++) {        var test = data[j];          if (test != current && result.indexOf(test) == -1 && ignore.indexOf(test) == -1) {          // If their fields match          if (test[field] == current[field]) {            for (var key in test) {              if (test.hasOwnProperty(key) && key != field) {                if (current.hasOwnProperty(key)) {                  var currentValues = current[key].split(", ");                  currentValues.push(test[key]);                  current[key] = currentValues.join(", ");                } else {                  current[key] = test[key];                }              }            }              // Add to ignore list            ignore.push(test);          }        }      }        if (ignore.indexOf(current) == -1) {        result.push(current);      }    }    return result;  }    var newData = groupBy('unit', data);  console.log(JSON.stringify(newData));  

Outputs:

[      {"unit":35,"brand":"CENTURY, BADGER"},      {"unit":25,"brand":"CENTURY, XEGAR"},      {"unit":15,"brand":"CENTURY"}  ]  

Answer by JNF for Group values on same property


OP asked for a solution using filter. Here is one, though not better than the rest

var arr = [{    unit: 35,    brand: 'CENTURY'  }, {    unit: 35,    brand: 'BADGER'  }, {    unit: 25,    brand: 'CENTURY'  }, {    unit: 15,    brand: 'CENTURY'  }, {    unit: 25,    brand: 'XEGAR'  }]  var done = [];    var arr2 = arr.map(function(obj) {    if (done.indexOf(obj.unit)>=0) return;    done.push(obj.unit);    var arrIn = arr.filter(function(objIn) {      return obj.unit == objIn.unit;    });    return {      unit: arrIn[0].unit,      brand: arrIn.map(function(obj2) {        return obj2.brand;      }).join(',')    };  });    document.write(JSON.stringify(arr2))

Answer by Nina Scholz for Group values on same property


This is a non-destructive solution with Array.prototype.filter() and a temporary object.

var array = [{ unit: 35, brand: 'CENTURY' }, { unit: 35, brand: 'BADGER' }, { unit: 25, brand: 'CENTURY' }, { unit: 15, brand: 'CENTURY' }, { unit: 25, brand: 'XEGAR' }];    function filter(a) {      var o = {};      return JSON.parse(JSON.stringify(a)).filter(function (b) {          if (!(b.unit in o)) {              o[b.unit] = b;              return true;          }          o[b.unit].brand += ', ' + b.brand;      });  }    document.write('
' + JSON.stringify(filter(array), 0, 4) + '
'); document.write('
' + JSON.stringify(array, 0, 4) + '
');


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.