2013-10-23 6 views
7

के साथ ऑब्जेक्ट को कम करना मैं इस ऑब्जेक्ट को उत्पाद नाम और औसत मूल्य वाले किसी ऑब्जेक्ट को कम करना चाहता हूं। ऐसा करने का सबसे तेज़ तरीका क्या है?मानचित्र अंडरस्कोर

var foo = { group1: [ 
     { 
      name: "one", 
      price: 100 
     }, 
     { 
      name: "two", 
      price: 100 
     }], 
     group2: [ 
     { 
      name: "one", 
      price: 200 
     }, 
     { 
      name: "two", 
      price: 200 
     }], 
     group3: [ 
     { 
      name: "one", 
      price: 300 
     }, 
     { 
      name: "two", 
      price: 300 
     }] 
     } 

में

var foo2 = [{ 
       name: 'one', 
       price: 200 
      },{ 
       name: 'two', 
       price: 200 
      }]; 

धन्यवाद जिसके परिणामस्वरूप!

+0

कहाँ '400' से आता है? – georg

उत्तर

0

संपादित करें: इसे अभी तक छोड़ना, लेकिन मैं पूरी तरह से _.flatten के बारे में भूल गया, इसलिए redmallard को much better answer मिला।

आप पहले से ही उत्पादों के नाम से जानते हैं और वे हर समूह में दिखाई हैं, तो आप पूरी बात जल्दी से इस तरह से कर सकता है:

var productAveragePrices = function (groups, names) { 
    return _.map(names, function (name) { 
    var product = { name: name }, productPricesSum = 0; 
    _.each(groups, function (group) { 
     productPricesSum += (_.findWhere(group, product).price); 
    }); 
    product.price = productPricesSum/_.size(groups); 
    return product; 
    }); 
}; 
var foo2 = productAveragePrices = function (foo, ['one', 'two']); 

मैं एक साथ डाल, जो काम करना चाहिए, भले ही आपके समूहों विभिन्न उत्पादों है (उदाहरण के लिए "एक" प्रथम, द्वितीय, और चौथे समूह में और "दो" पहले और तीसरे में):

var productPriceReducer = function(memo, group) { 
    _.each(group, function(product) { 
    // Grabs the current product from the list we're compiling 
    var memoProduct = _.findWhere(memo, { name: product.name }); 
    if (!memoProduct) { 
     // If the product doesn't exist, creates a holder for it and its prices 
     memoProduct = { 
     name: product.name, 
     prices: [ product.price ] 
     }; 
     memo.push(memoProduct); 
    } else { 
     // Otherwise, it just adds the prices to the existing holder. 
     memoProduct.prices.push(product.price); 
    } 
    }); 
    return memo; 
}; 

// This gets us a list of products with all of their prices across groups 
var productPrices = _.reduce(foo, productPriceReducer, []); 

// Then reducing to the average is pretty simple! 
var productAveragePrices = _.map(productPrices, function (product) { 
    var sumPrices = _.reduce(product.prices, function (memo, price) { 
    return memo + price; 
    }, 0); 
    return { 
    name: product.name, 
    price: sumPrices/product.prices.length 
    }; 
}); 

तुम अब भी कर सकता है एक काउंटर के साथ एक समारोह में और कीमतों संक्षेप ऊपर है, लेकिन इस तरह से , यदि आप चाहते हैं कि कीमतें भी हों, तो मानक डी लें विचलन या मोड ढूंढें।

+0

अच्छा! धन्यवाद एक टन – vincewilfork

+0

मेरी खुशी। मेरे पहले स्वीकृत उत्तर के लिए धन्यवाद! – Evan

20

इवान की परेड पर नहीं बारिश, लेकिन यहाँ एक विकल्प है कि थोड़ा कम है है,)

result = _.chain(original) 
    .flatten() 
    .groupBy(function(value) { return value.name; }) 
    .map(function(value, key) { 
    var sum = _.reduce(value, function(memo, val) { return memo + val.price; }, 0); 
    return {name: key, price: sum/value.length}; 
    }) 
    .value(); 

कार्य करते हुए देखें: http://plnkr.co/edit/lcmZoLkrlfoV8CGN4Pun?p=preview

+3

यह बेहतर है! +1 – Evan

+3

.groupBy (फ़ंक्शन (मान) {वापसी मान.नाम;}) को बस .groupBy ('name') के रूप में लिखा जा सकता है। – user239558

3

मैं वास्तव में redmallard के समाधान की तरह है, लेकिन मैं गोल्फ करना चाहता था थोड़ा सा।

अंडरस्कोर में sum फ़ंक्शन शामिल नहीं है, लेकिन हम sum मिश्रण जोड़कर सुंदर सुरुचिपूर्ण कार्यात्मक अभिव्यक्तियां लिख सकते हैं। अंडरस्कोर-contribs रेपो में यह फ़ंक्शन add के रूप में जाना जाता है।

तो हम लिख सकते हैं:

// Somewhere in the initialization of the program 
_.mixin({ 
    sum : function (arr) { 
    return _.reduce(arr, function (s, x) { return s + x;}, 0); 
    } 
}); 
result = _.chain(original) 
    .flatten() 
    .groupBy('name') // shorthand notation 
    .map(function (value, key) { 
     var sum = _.chain(value).pluck('price').sum().value(); 
     return { name: key, price: sum/value.length}; 
    }) 
    .value(); 

http://plnkr.co/edit/ul3odB7lr8qwgVIDOtM9

लेकिन तब हम भी एक avg mixin बना सकते हैं हमारे टूलबेल्ट विस्तार करने के लिए:

// Somewhere in the initialization of the program 
_.mixin({ 
    sum : function (arr) { 
    return _.reduce(arr, function (s, x) { return s + x;}, 0); 
    }, 
    avg : function (arr) { 
    return _.sum(arr)/arr.length; 
    } 
}); 
result = _.chain(original) 
    .flatten() 
    .groupBy('name') // shorthand notation 
    .map(function (value, key) { 
     return { name: key, price: _.avg(value)}; 
    }) 
    .value(); 
संबंधित मुद्दे