2013-02-13 27 views
5

में समान तत्वों का मतलब गणना करता है मुझे एक सरणी के रूप में प्रतिनिधित्व किए गए दो स्तंभों की 'तालिका' मिली है।जेएस 2 डी सरणी

my_array = [ [ 3,4,5,3,4,5,2 ],[ 12,14,16,11,12,10,20 ] ]; 

मैं मतलब (औसत) हर लेबल के लिए की जरूरत है::

my_mean_array = [ [ 2,3,4,5 ],[ 20/1, (12+11)/2, (14+12)/2, (16+10)/2 ] ]; 
// edit: The mean should be a float - the notion above is just for clarification. 
// Also the number 'labels' should remain as numbers/integers. 

पहले कॉलम 1 से 20 नंबर दिए गए हैं और वे लेबल हैं, दूसरे स्तंभ संबंधित मानों (सेकंड) कर रहे हैं मेरे कोशिश:

var a = my_array[0]; 
var b = my_array[1]; 
m = []; 
n = []; 
for(var i = 0; a.length; i++){ 
    m[ a[i] ] += b[i]; // accumulate the values in the corresponding place 
    n[ a[i] ] += 1; // count the occurences 
} 
var o = []; 
var p = []; 
o = m/n; 
p.push(n); 
p.push(o); 

उत्तर

3

यह कैसे (देशी जे एस के बारे में, होगा पुराने ब्राउज़र पर नहीं तोड़):

function arrayMean(ary) { 
    var index = {}, i, label, value, result = [[],[]]; 

    for (i = 0; i < ary[0].length; i++) { 
    label = ary[0][i]; 
    value = ary[1][i]; 
    if (!(label in index)) { 
     index[label] = {sum: 0, occur: 0}; 
    } 
    index[label].sum += value; 
    index[label].occur++; 
    } 
    for (i in index) { 
    if (index.hasOwnProperty(i)) { 
     result[0].push(parseInt(i, 10)); 
     result[1].push(index[i].occur > 0 ? index[i].sum/index[i].occur : 0); 
    } 
    } 
    return result; 
} 

Fwiw, आप कल्पना मैं कुछ अन्य तरीके यह करने के लिए बना लिया है चाहते हैं। वे बाहरी पुस्तकालयों पर निर्भर करते हैं और शायद मूल समाधान की तुलना में धीमी गति का क्रम भी हैं। लेकिन वे देख रहे हैं nicer।

यह underscore.js साथ, ऐसा दिखाई दे सकता:

function arrayMeanUnderscore(ary) { 
    return _.chain(ary[0]) 
    .zip(ary[1]) 
    .groupBy(function (item) { return item[0]; }) 
    .reduce(function(memo, items) { 
     var values = _.pluck(items, 1), 
      toSum = function (a, b) { return a + b; }; 

     memo[0].push(items[0][0]); 
     memo[1].push(_(values).reduce(toSum)/values.length); 
     return memo; 
    }, [[], []]) 
    .value(); 
} 

// -------------------------------------------- 

arrayMeanUnderscore([[3,4,5,3,4,5,2], [12,14,16,11,12,10,20]]); 
// -> [[2,3,4,5], [20,11.5,13,13]] 

या इस तरह, सही मायने में महान linq.js (मैं का उपयोग किया है v2.2) के साथ:

function arrayMeanLinq(ary) { 
    return Enumerable.From(ary[0]) 
    .Zip(ary[1], "[$, $$]") 
    .GroupBy("$[0]") 
    .Aggregate([[],[]], function (result, item) { 
     result[0].push(item.Key()); 
     result[1].push(item.Average("$[1]")); 
     return result; 
    }); 
} 

// -------------------------------------------- 

arrayMeanLinq([[3,4,5,3,4,5,2], [12,14,16,11,12,10,20]]); 
// -> [[3,4,5,2], [11.5,13,13,20]] 

के रूप में संदिग्ध, "फैंसी" कार्यान्वयन मूल कार्यान्वयन की तुलना में धीमी गति का क्रम है: jsperf comparison

+0

धन्यवाद! - मैन जेएस सीधे आगे नहीं है ... – Chrugel

+0

कुछ सुधार: - मुझे लगता है कि अगर परीक्षण: index.hasOwnProperty (i) उपयोगकर्ता रहित है। - मुझे लगता है कि parseInt बेकार है क्योंकि my_array की संख्या है। - यदि होता है तो परीक्षण करने के लिए 0 है, वाक्य का उपयोग करें? बजाय। ocurr == 0 0: राशि/होते हैं। –

+0

बस स्पष्ट करने के लिए: सभी को धन्यवाद! मैंने बस यह जवाब चुना है, बी/सी यह मुझे बॉक्स के बाहर सही/अपेक्षित परिणाम देता है। रॉबर्टक्लेप और एड्रियन मायर से (बहुत ही सुरुचिपूर्ण) समाधान के साथ मैं अपने 'लेबल'-सबराय में तारों के साथ समाप्त होता हूं, जो कोई समस्या नहीं है, लेकिन तोमालाक ने एक उपयुक्त समाधान दिया। – Chrugel

0
var temp = {}; 
my_array[0].map(function(label, i) { 
    if (! temp[label]) 
    { 
    temp[label] = []; 
    } 
    temp[label].push(my_array[1][i]); 
}); 
var result = [ [], [] ]; 
for (var label in temp) { 
    result[0].push(label); 
    result[1].push(
    temp[label].reduce(function(p, v) { return p + v })/temp[label].length 
); 
} 
0

यह फ़ंक्शन परिणामस्वरूप सरणी को आपके परिणाम उदाहरण में सॉर्ट नहीं करता है। अगर आपको सॉर्टिंग की ज़रूरत है, तो बस मुझे कहें और मैं इसे जोड़ दूंगा।

function getMeanArray(my_array) 
{ 
    m = {}; //id={count,value} 
    for(var i = 0; i<my_array[0].length; i++){ 
     if (m[my_array[0][i]]===undefined) 
     { 
      m[my_array[0][i]]={count:0, value:0}; 
     } 
     m[ my_array[0][i] ].value += my_array[1][i]; // accumulate the values in the corresponding place 
     m[ my_array[0][i] ].count++; // count the occurences 
    } 
    var my_mean_array=[[],[]]; 
    for (var id in m) 
    { 
     my_mean_array[0].push(id); 
     my_mean_array[1].push(m[id].count!=0?m[id].value/m[id].count:0); 
    } 
    return my_mean_array; 
} 
संबंधित मुद्दे