簡體   English   中英

使用功能編程對2D數組中的列求平均值

[英]Average a columns in a 2D array with functional programming

作為函數式編程的一項練習,我決定遍歷我的一個項目,並用Array.prototype高階函數(例如mapreduce替換包含for循環的函數

我項目中的一個函數將二維數組中的列平均。 它接受一個參數samples ,該samples是大小為[n][LOOKBACK]的二維數組:

[
    [0.6,  4.0, -0.5],
    [1.0, -0.5, -0.8],
    ...
]

 const LOOKBACK = 3 function averageChange(samples) { let result = [] let count = 0, i, j for (i = 0; i < LOOKBACK; i++) { let accumulator = 0 for (j = 0; j < samples.length; j++) { accumulator += samples[j][i] } result.push(accumulator / samples.length) } return result } console.log( averageChange([ [0.6, 4.0, -0.5], [1.0, -0.5, -0.8] ]) ) 

輸出應為大小為LOOKBACK的數組,其元素是每一列的平均值:

[0.8, 1.75, -0.65]

我花了一些時間試圖找到解決方案,但是我似乎無法提出一個解決方案。

使用Javascript的內置Array函數可以做到這一點嗎?

*更新

從Kirill獲得了一個優雅的解決方案。 如果其他人有很好的解決方案,我希望看到更多。

使用reduceforEach函數嘗試以下示例:

 let a = [ [0.6, 4.0, -0.5], [3.0, -0.5, -0.1], [1.0, -0.2, -0.8], [7.0, -0.5, -0.8] ]; let b = a.reduce((acc, cur) => { cur.forEach((e, i) => acc[i] = acc[i] ? acc[i] + e : e); return acc; }, []).map(e => e / a.length); console.log(b); 

這是矩陣轉置的更巧妙的方法:

 let a = [ [0.6, 4.0, -0.5], [3.0, -0.5, -0.1], [1.0, -0.2, -0.8], [7.0, -0.5, -0.8] ]; let b = a[0].map((col, i) => a.map(row => row[i]).reduce((acc, c) => acc + c, 0) / a.length); console.log(b); 

介紹..

函數式編程不僅僅是編寫單行代碼 ,還使用諸如Arary#mapArray#reduceArray#filter 類的高階函數 順便說一句, Array#forEach不起作用,因為它不是純函數 ..

除了高階函數 ,你可以使用鑽營功能成分 ,和更多

算法

我們要做的是:

  1. 重新排列矩陣
  2. 計算矩陣內每個數組的平均值

在JavaScript中看起來可能像這樣:

const averageChange = pipe(
    rearrange ([]),
    map (average) 
)

pipe是將多個功能組合成一個巨大功能的功能。 現在, averageChange需要一個參數,它將通過管道傳遞。

改編

const rearrange = yss => xss => 
    xss[0].length === 0
        ? yss
        : rearrange
            (concat (yss) ([ map ( getIndex (0) ) ( xss ) ]))
            (map ( slice (1, xss[0].length) ) ( xss ))

這看起來真的很神秘。 由於咖喱和功能組成,我們可以重寫它:

const rearrange = yss => xss => 
    matrixLength (xss) === 0
        ? yss
        : rearrange
            (concat (yss) ([ firstIndeces ( xss ) ]))
            (excludeFirstIndeces ( xss ))

rearrange是一種遞歸函數,可將矩陣從

[
    [0.6,  4.0, -0.5],
    [3.0, -0.5, -0.1],
    [1.0, -0.2, -0.8],
    [7.0, -0.5, -0.8]
]

[ 
    [ -0.5, -0.1, -0.8, -0.8 ],
    [  4  , -0.5, -0.2, -0.5 ],
    [  0.6,  3  ,  1  ,  7   ] 
]

工作代碼示例

我編寫的代碼比其他解決方案要多得多,但是我將邏輯划分為自己的函數,這意味着我們現在可以對代碼的其他部分使用average函數。 另外,我已經為Array#map等編寫了可簡化版本以組成它們。 如果使用庫,那將是多余的。

 // helper functions const pipe = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args))) const getIndex = i => xs => xs[i] const map = f => xs => xs.map(f) const reduce = f => seel => xs => xs.reduce(f) const concat = ys => xs => xs.concat(ys) const slice = (start, end) => xs => xs.slice(start, end) const average = xs => reduce ((sum, x) => sum + x) (0) (xs) / xs.length const length = xs => xs.length const matrixLength = pipe( getIndex(0), length ) const firstIndex = getIndex (0) const firstIndeces = map ( firstIndex ) const excludeFirstIndex = xss => slice (1, matrixLength (xss)) (xss) const excludeFirstIndeces = map ( excludeFirstIndex ) // business logic const rearrange = yss => xss => matrixLength (xss) === 0 ? yss : rearrange (concat (yss) ([ firstIndeces ( xss ) ])) (excludeFirstIndeces ( xss )) const averageChange = pipe ( rearrange ([]), map(average) ) const values = [ [0.6, 4.0, -0.5], [3.0, -0.5, -0.1], [1.0, -0.2, -0.8], [7.0, -0.5, -0.8] ] console.log( averageChange (values) ) 

var a=[];var b=[];
var i = 0; j = 0;

cubes.forEach(function each(item,length) {
  if (Array.isArray(item)) {
    item.forEach(each);
    j++;
    i = 0;
  } else {
    if(a[i]===undefined){
        a[i]=0;b[i]=0}
    a[i]=(a[i]*b[i]+item)/(b[i]+1);
    b[i]=b[i]+1;
    i++;
  }
});
console.log(a);

即使對於不同的內部數組大小,這也將起作用。類似[[1],[2,3,4]]

 cubes=[[1],[1,2,3]] var a=[];var b=[]; var i = 0; j = 0; cubes.forEach(function each(item,length) { if (Array.isArray(item)) { item.forEach(each); j++; i = 0; } else { if(a[i]===undefined){ a[i]=0;b[i]=0} a[i]=(a[i]*b[i]+item)/(b[i]+1); b[i]=b[i]+1; i++; } }); console.log(a); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM