objetos - map javascript
¿Hay una forma funcional de iniciar una matriz en JavaScript ES6? (6)
El ejemplo de .from()
es excelente, pero si realmente desea ser creativo, compruebe esto.
const newArray = length => [...`${Math.pow(10, length) - 1}`]
newArray(2)
newArray(10)
Aunque masivamente limitado
newArray(1000)
["I", "n", "f", "i", "n", "i", "t", "y"]
Finalmente, me di por vencido y escribí un bucle for
para inicializar una matriz simple de objetos donde cada objeto tiene un contador ( id
) incrementado como atributo del objeto. En otras palabras, solo quiero:
var sampleData = [{id: 1},{id: 2},...];
Esperaba una sintaxis compacta que pudiera poner en mi declaración de devolución.
let sampleData = [];
for (var p = 0; p < 25; p++){
sampleData.push({id: p});
}
return {
data: sampleData,
isLoading: true
};
Estás buscando un anamorfismo, o pliegue inverso -
// unfold : ( (r, state) -> List r, () -> 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 } ]
Puede obtener una intuición de cómo funciona el unfold
viéndolo usado en otros programas comunes.
// unfold : ( (r, state) -> List r, () -> 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 ]
La implementación del unfold
es solo una posibilidad. Consigue retoques e implementa de la forma que elijas -
// type Maybe a = Nothing | Just a
const Just = x =>
({ match: ({ Just: f }) => f (x) })
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 ]
Hice trampa un poco arriba usando un []
como una tupla. Esto mantuvo el programa más corto, pero es mejor modelar las cosas explícitamente y considerar sus tipos. Etiquetó esta pregunta con programación funcional, por lo que vale la pena hacer un esfuerzo adicional para eliminar este tipo de manejo implícito de nuestros programas. Al mostrar esto como un paso separado, aislamos una técnica que se puede aplicar no solo para unfold
, sino para cualquier programa que diseñemos:
// type Maybe a = Nothing | Just a
const Just = x =>
({ match: ({ Just: f }) => f (x) })
const Nothing = () =>
({ match: ({ Nothing: f }) => f () })
// type Tuple a b = { first: a, second: 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 ]
Lo que suelo hacer es esto:
const data = Array(10).fill().map((v, i) => ({id: i + 1}))
fill
asegura que se puede utilizar con el map
Puede usar el operador de spread
con Array
y luego asignar cada elemento undefined
al objeto que desee.
var arr = [...Array(10)].map((_,i)=>({id:i}));
console.log(arr)
Puedes usar un proceso recursivo simple para hacer eso.
const iter = (arr, counter) => {
if (counter === 25) return arr;
return iter([...arr, {id:counter}], counter + 1)
}
iter([], 0)
Array.from()
es una buena manera de hacer esto. Puede pasar un objeto {length: somlength}
u otro objeto similar a una matriz y una función que define cada elemento. El primer argumento (llamándolo _
solo para indicar que no se usa) a esa función sería el elemento de una matriz que pasamos (pero solo pasamos en una longitud, por lo que no significa mucho), el segundo es el índice , que se utiliza para su id
:
let sampleData = Array.from({length: 10}, (_, id) => ({id}))
console.log(sampleData)