3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaScript: for-loop から reduce へ

Last updated at Posted at 2019-04-01

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 } ] }
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?