是否有一种在JavaScript ES6中初始化数组的功能方法?

Pet*_*ete 28 javascript functional-programming ecmascript-6

我终于放弃并编写了一个for循环来初始化一个简单的对象数组,其中每个对象都有一个递增的counter(id)作为对象的属性.换句话说,我只想要:

var sampleData = [{id: 1},{id: 2},...];
Run Code Online (Sandbox Code Playgroud)

我希望有一个紧凑的语法,我可以把它放在我的返回语句上.

let sampleData = [];
for (var p = 0; p < 25; p++){
    sampleData.push({id: p});
}

return {
    data: sampleData,
    isLoading: true
};
Run Code Online (Sandbox Code Playgroud)

Mar*_*yer 44

Array.from()这是一个很好的方法.您可以传递一个{length: somlength}对象或其他类似数组的对象以及定义每个项目的函数.该函数的第一个参数(_只是为了表明它没有被使用)将是我们传入的数组中的项(但我们只传入一个长度所以它并不意味着太多),第二个i是索引,用于你的id:

let sampleData = Array.from({length: 10}, (_, id) => ({id}))

console.log(sampleData)
Run Code Online (Sandbox Code Playgroud)

  • @Pete,你问的是什么 - 看起来像一个角色没有通过.我添加了一些关于`_`它只是一个函数参数 - 本来可以调用它.我有时会使用`_`作为未使用或未定义的参数. (5认同)
  • 除此之外,还有不少语言包含`_`作为实际语言功能.它实际上会忽略这个价值.我能想到的两个例子就是Rust和Haskell.在Javascript中,`_`纯粹是约定,实际上是赋值.例如,`const a = _ =>"hi"+ _;`是有效代码.它实际上只是一个标识符.这是传达意图而不是改变它的工作方式. (2认同)

jia*_*ian 15

我通常做的是:

const data = Array(10).fill().map((v, i) => ({id: i + 1}))
Run Code Online (Sandbox Code Playgroud)

fill 确保它可以使用 map


Joh*_*anP 8

您可以使用spread运算符,Array然后将每个undefined元素映射到所需的对象.

var arr = [...Array(10)].map((_,i)=>({id:i}));
console.log(arr)
Run Code Online (Sandbox Code Playgroud)

  • 是的,`Array(10)`只设置`length`,它没有任何项目. (4认同)
  • 假设 `[...Array(10)]` 相当于 `Array(10).fill()`,后者不是更具可读性吗?不可否认,我对人们在 Javascript 中发现的内容没有很好的直觉...... (2认同)

Tha*_*you 6

您正在寻找变形或反折–

// unfold : ((r, state) -> List r, unit -> List r, state) -> List r
const unfold = (f, init) =>
  f ( (x, next) => [ x, ...unfold (f, next) ]
    , () => [] 
    , init
    )
    
// sampleData : List { id: Int }
const sampleData =
  unfold
    ( (next, done, i) =>
        i > 25
          ? done ()
          : next ({ id: i }, i + 1)
    , 0
    )
    
console .log (sampleData)
// [ { id: 0 }, { id : 1 }, ... { id: 25 } ]
Run Code Online (Sandbox Code Playgroud)

您可以unfold通过查看其他常见程序中使用的方法来直观了解其工作原理–

// unfold : ((r, state) -> List r, unit -> List r, state) -> List r
const unfold = (f, init) =>
  f ( (x, next) => [ x, ...unfold (f, next) ]
    , () => []
    , init
    )
    
// fibseq : Int -> List Int
const fibseq = init =>
  unfold
    ( (next, done, [ n, a, b ]) =>
         n === 0
           ? done ()
           : next (a, [ n - 1, b, a + b ])
    , [ init, 0, 1 ]
    )
    
console .log (fibseq (10))
// [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ]
Run Code Online (Sandbox Code Playgroud)

实现unfold只是一种可能性。自行修改并以您选择的方式实施–

// type Maybe a = Nothing | Just a    

// Just : a -> Maybe a
const Just = x =>
  ({ match: ({ Just: f }) => f (x) })

// Nothing : unit -> Maybe a
const Nothing = () =>
  ({ match: ({ Nothing: f }) => f () })

// unfold : (state -> Maybe (a, state), state) -> List a  
const unfold = (f, init) =>
  f (init) .match
    ( { Nothing: () => []
      , Just: ([ x, next ]) => [ x, ...unfold (f, next) ]
      }
    )

// fibseq : Int -> List Int
const fibseq = init =>
  unfold
    ( ([ n, a, b ]) =>
        n === 0
          ? Nothing ()
          : Just ([ a, [ n - 1, b, a + b ] ]) // <-- yikes, read more below
    , [ init, 0, 1 ]
    )
    
console .log (fibseq (10))
// [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ]
Run Code Online (Sandbox Code Playgroud)

我使用a []作为元组在上面作弊。这使程序更短,但是最好对事物进行显式建模并考虑其类型。您使用函数式编程标记了这个问题,因此值得花一点时间从我们的程序中删除这种隐式处理。通过将其显示为一个单独的步骤,我们隔离了一种不仅可以应用于unfold,而且可以应用于我们设计的任何程序的技术-

// type Maybe a = Nothing | Just a
// type Tuple a b = { first: a, second: b }

// Just : a -> Maybe a
const Just = x =>
  ({ match: ({ Just: f }) => f (x) })

// Nothing : unit -> Maybe a
const Nothing = () =>
  ({ match: ({ Nothing: f }) => f () })

// Tuple : (a, b) -> Tuple a b
const Tuple = (first, second) =>
  ({ first, second })

// unfold : (state -> Maybe Tuple (a, state), state) -> List a  
const unfold = (f, init) =>
  f (init) .match
    ( { Nothing: () => []
      , Just: (t) => [ t.first, ...unfold (f, t.second) ] // <-- Tuple
      }
    )

// fibseq : Int -> List Int
const fibseq = init =>
  unfold
    ( ([ n, a, b ]) =>
        n === 0
          ? Nothing ()
          : Just (Tuple (a, [ n - 1, b, a + b ])) // <-- Tuple
    , [ init, 0, 1 ]
    )
    
console .log (fibseq (10))
// [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ]
Run Code Online (Sandbox Code Playgroud)