javascript - Group objects in array by property -
i have started pick coding seriously. :) came across problem seems complicated me.
how group following products promotions type?
var data = [ { name:'product1', price:'40', promotion:[ { name:'buy 3 30% off', code:'ewq123' }, { name:'free gift', code:'abc140' } ] }, { name:'product2', price:'40', promotion:[ { name:'buy 3 30% off', code:'ewq123' } ] }, { name:'product3', price:'40', promotion:[ { name:'buy 3 30% off', code:'ewq123' } ] }, { name:'product4', price:'40' }, { name:'product5', price:'40', promotion:[ {name:'30% off', code:'fnj245'} ] }, { name:'product6', price:'0', promotion:[ { name:'free gift', code:'abc140' } ] } ];
i result in following format
result =[ { name : 'buy 3 30% off', code: 'ewq123', products: [ ... array of products ] }, { name : '30% off', code: 'fnj245', products: [ ... array of products ] }, { ... } ];
i able list of products promotion code, how can make generic?
function producthaspromo(product, promotion){ if(!product.hasownproperty('promotion')) return false; var productpromo = product.promotion; for(var i=0; i<productpromo.length; i++){ if(productpromo[i].code === promotion){ return true; } } return false; } function groupproductbypromo(products, promotion){ var arr = []; for(var i=0; i<products.length; i++){ if(producthaspromo(products[i], promotion)){ arr.push(products[i]); } } return arr; }
explanation
you write function loops through array , search unique values within specified property. done when working simple data types, can done more complex structures arrays of objects (like in example), using helper grouping
function.
since need output in specific format after grouping, have work on transformer
also. transformer receive original data , unique values extracted grouping
function, , generate desired output.
the following functions used in example:
array.prototype.groupby = function (property, grouping, transformer) { var values = []; this.foreach(function (item) { grouping.call(this, item, property).foreach(function (item) { if (!values.contains(property, item[property])) { values.push(item); } }); }); return transformer.call(this, values); }; array.prototype.contains = function (key, value) { return this.find(function (elm) { return elm[key] === value; }); }; function transformerfunction(values) { this.foreach(function (item) { if (!item.promotion) return; item.promotion.foreach(function (promotion) { values.foreach(function (option) { if (option.code === promotion.code) { if (option.products) { option.products.push(item); } else { option.products = [item]; } } }); }); }); return values; } function groupingfunction(item, property) { if (!item.promotion) return []; var values = []; item.promotion.foreach(function (promotion) { if (!values.contains(property, promotion[property])) { values.push(promotion); } }); return values; }
usage follows:
var items = data.groupby('code', groupfunction, transformfunction);
example
check example i've prepared @ jsfiddle
Comments
Post a Comment