web-dev-qa-db-fra.com

Existe-t-il un moyen fonctionnel d’initialiser un tableau dans JavaScript ES6?

J'ai finalement abandonné et écrit une boucle for pour initialiser un simple tableau d'objets dans lequel chaque objet possède un compteur incrémenté (id) en tant qu'attribut de l'objet. En d'autres termes, je veux juste:

var sampleData = [{id: 1},{id: 2},...];

J'espérais une syntaxe compacte que je pourrais simplement mettre dans ma déclaration de retour.

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

return {
    data: sampleData,
    isLoading: true
};
27
Pete

Array.from() est une bonne façon de faire cela. Vous pouvez passer un {length: somlength} objet ou un autre objet de type tableau et une fonction qui définit chaque élément. Le premier argument (l'appelant _ _ juste pour indiquer qu’elle n’est pas utilisée) à cette fonction serait l’élément d’un tableau que nous avons transmis (mais nous n’avons passé qu’une longueur, cela ne veut donc pas dire grand chose), le second i est l’index , qui est utilisé pour votre id:

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

console.log(sampleData)
44
Mark Meyer

Ce que je fais habituellement est la suivante:

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

fill s'assure qu'il peut être utilisé avec map

14
yidaohuuu

Vous pouvez utiliser l'opérateur spread avec Array, puis mapper chaque élément undefined à l'objet souhaité.

var arr = [...Array(10)].map((_,i)=>({id:i}));
console.log(arr)
8
JohanP

Vous recherchez un anamorphisme ou un repli inverse -

// 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 } ]

Vous pouvez avoir une intuition sur le fonctionnement de unfold en le voyant utilisé dans d’autres programmes courants -

// 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 ]

L'implémentation de unfold n'est qu'une possibilité. Obtenez le bricolage et mettez-le en œuvre selon votre choix -

// 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 ]

J'ai triché un peu plus haut en utilisant un [] comme un tuple. Le programme a donc été raccourci, mais il est préférable de modéliser explicitement les choses et de considérer leurs types. Vous avez associé cette question à fonctionnal-programmation, il est donc utile de redoubler d'efforts pour supprimer ce type de traitement implicite de nos programmes. En montrant cela comme une étape séparée, nous isolons une technique qui peut être appliquée non seulement à unfold, mais à tout programme que nous concevons -

// 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 ]
6
user633183

L'exemple .from() est excellent, mais si vous voulez vraiment faire preuve de créativité, vérifiez-le.

const newArray = length => [...`${Math.pow(10, length) - 1}`]
newArray(2)
newArray(10)

Massivement limité cependant

newArray(1000)
["I", "n", "f", "i", "n", "i", "t", "y"]
4
stwilz

Vous pouvez utiliser un processus récursif simple pour le faire.

const iter = (arr, counter) => {
  if (counter === 25) return arr;
  return iter([...arr, {id:counter}], counter + 1)
}
iter([], 0)
2