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:
- the value of the element
- the index of the element
- 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