JavaScript: 「最初はこうだったけど、いろいろあって、こうなった」reduceは状態遷移だの続き。
for-loopとreduceで同じことをやって並べてみました。
比較のためにreduceは分かち書きしてます。
こんなfor-loopを書いていたら、そこは reduce に置きかえられるかも?という例です。
MDNのreduceの例から引用。
sum
//for-loop
const sum = msgs =>{
let model = 0
for(let msg of msgs) model = model + msg
return model
}
const items = [0,1,2]
sum(items) // 3
//reduce
const initModel = 0
const update = ( model, msg) => model + msg
const sum = msgs => msgs.reduce(update, initModel)
const items = [0, 1, 2]
sum(items) // 3
オブジェクトの配列の値の合計値
//for-loop
const sumX = msgs =>{
let model = 0
for(let msg of msgs) model = model + msg.x
return model
}
const items = [{x:1}, {x:2}, {x:3}]
sumX(items) // 6
//reduce
const initModel = 0
const update = ( model, msg ) => model + msg.x
const sumX = msgs => msgs.reduce(update, initModel)
const items = [{x:1}, {x:2}, {x:3}]
sumX(items) // 6
二次元配列を一次元配列に
//for-loop
const flatten = msgs =>{
let model = []
for( let msg of msgs ) model = [...model, ...msg]
return model
}
const items = [[0, 1], [2, 3], [4, 5]]
flatten(items) // [ 0, 1, 2, 3, 4, 5 ]
//reduce
const initModel = []
const update = ( model, msg ) => [...model, ...msg]
const flatten = msgs => msgs.reduce(update, initModel)
const items = [[0, 1], [2, 3], [4, 5]]
flatten(items) // [ 0, 1, 2, 3, 4, 5 ]
オブジェクトの値のインスタンスを数える
//for-loop
const countedNames = msgs =>{
let model = {}
for(let msg of msgs) {
if(e in model) model[msg] = model[msg] + 1
else model[msg] = 1
}
return model
}
const items = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']
countedNames(items) // { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
//reduce
const initModel = {}
const update = ( model, msg) =>
msg in model? {...model, [msg]: model[msg] + 1}
: {...model, [msg]:1}
const countedNames = msgs => msgs.reduce(update, initModel)
const items = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']
countedNames(items) // { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
プロパティによってオブジェクトをグループ化する
//for-loop
const groupBy = prop => msgs => {
let model = {}
for(let msg of msgs) {
const key = msg[prop]
if( model[key] === undefined ) model[key] = [msg]
else model[key] = [...model[key], msg]
}
return model
}
const items = [
{ name: 'Alice', age: 21 },
{ name: 'Max', age: 20 },
{ name: 'Jane', age: 20 }
]
groupBy('age')(items)
// { '20': [ { name: 'Max', age: 20 }, { name: 'Jane', age: 20 } ],'21': [ { name: 'Alice', age: 21 } ] }
//reduce
const initModel = {}
const update = prop => ( model, msg) => {
const key = msg[prop]
return model[key] === undefined ? { ...model, [key]:[msg] }
: { ...model, [key]:[...model[key], msg] }
}
const groupBy = prop => msgs =>
msgs.reduce( update(prop), initModel )
const items = [
{ name: 'Alice', age: 21 },
{ name: 'Max', age: 20 },
{ name: 'Jane', age: 20 }
]
groupBy('age')(items)
// { '20': [ { name: 'Max', age: 20 }, { name: 'Jane', age: 20 } ],'21': [ { name: 'Alice', age: 21 } ] }