點燈坊

失くすものさえない今が強くなるチャンスよ

使用 insert() 將單一值新增至指定 Index 的 Array

Sam Xiao's Avatar 2020-02-01

若要將單一值新增至 Array 中指定 Index,原本 Element 全部往後移,Ramda 提供了 insert()

Version

macOS Catalina 10.15.2
VS Code 1.41.1
Quokka 1.0.274
Ramda 0.26.1

Imperative

let data = [1, 2, 3]

let insert = idx => val => arr => {
  let result = []

  for(let i = 0; i < arr.length; i++) {
    if (i === idx)
      result.push(val, arr[i])
    else 
      result.push(arr[i])
  }

  return result
}

insert(1)(0)(data) // ?

Imperative 會藉由 for loop 判斷 index,藉由 ES6 的 ... array spread 可輕易將指定 value 插入 array。

insert000

reduce()

let data = [1, 2, 3]

let insert = idx => val => arr => arr.reduce(
  (a, x, i) => (i === idx) ? [...a, val, x] : [...a, x]
, [])

insert(1)(0)(data) // ?

也能使用 reduce() 改寫,別忘了 reduce() 的第三個 parameter 為 index,因此可用來判斷指定 index。

insert001

splice()

let data = [1, 2, 3]

let insert = idx => val => arr => {
  let result = arr.slice()
  result.splice(idx, 0, val)
  return result
}

insert(1)(0)(data) // ?

insert() 也能使用 Array.prototype.splice() 實現,唯 splice() 會直接修改 array,而非回傳新 array,由於 array 是以 pass by reference 傳進 function,因此會 side effect 影響到原本 data,因此特別使用 slice() clone 了一份 result,如此就可安全使用 splice()

insert002

Ramda

import { insert } from 'ramda'

let data = [1, 2, 3]

insert(1)(0)(data) // ?

Ramda 提供了 insert(),可直接使用。

insert()
Number → a → [a] → [a]
將單一值新增至指定 index 的 array

Number:指定 index

a:要新增的 element

[a]:data 為 array

[a]:回傳新 array

insert003

Conclusion

  • splice() 雖然也能對 array 做 insert,但其為 destructive 會直接修改原本 array,須小心使用,實務上建議使用 Ramda 的 insert()

Reference

MDN, Array.prototype.slice()
MDN, Array.prototype.splice()
Ramda, insert()