Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

236
Vistas
Ramda: extrae dos propiedades y agrega una al otro estilo sin puntos

Tengo algunos datos en el formulario:

 const data = { list: [1, 2, 3], newItem: 5 }

Quiero hacer una función que agregue el valor de newItem a la list lo que da como resultado esta nueva versión de data :

 { list: [1,2,3,5], newItem: 5, }

(En última instancia, eliminaría newItem después de que se haya movido a la lista, pero estoy tratando de simplificar el problema para esta pregunta).

Estoy tratando de hacerlo usando estilo sin puntos y Ramda.js, como una experiencia de aprendizaje.

Aquí es donde estoy hasta ahora:

 const addItem = R.assoc('list', R.pipe( R.prop('list'), R.append(R.prop('newItem')) ) )

La idea es generar una función que acepte data , pero en este ejemplo, la llamada a R.append también necesita una referencia a datos, estoy tratando de evitar mencionar data explícitamente para mantener el estilo Pointfree.

¿Es posible hacerlo sin mencionar data ?

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

Si entiendo correctamente, desea pasar de {x:3, y:[1,2]} a [1,2,3] . Aquí hay una manera:

 const fn = compose(apply(append), props(['x', 'y'])) fn({x:3, y:[1,2]}); //=> [1,2,3]
about 4 years ago · Juan Pablo Isaza Denunciar

0

Como muestra la discusión sobre la respuesta de customcommander, hay dos posibles interpretaciones diferentes.

Si solo desea recibir [1, 2, 3, 5] , puede hacerlo como lo hace customcommander, o de la forma en que yo elegiría:

 const fn1 = lift (append) (prop ('newItem'), prop ('list'))

Pero si quisiera algo como {list: [1, 2, 3, 5], newItem: 5} , entonces podría usar lo anterior dentro de applySpec y combinarlo con una combinación, como esta:

 const fn2 = chain (mergeLeft, applySpec ({list: fn1}))

Aquí hay un fragmento:

 const fn1 = lift (append) (prop ('newItem'), prop ('list')) const fn2 = chain (mergeLeft, applySpec ({list: fn1})) const data = {list: [1, 2, 3], newItem: 5} console .log (fn1 (data)) //=> [1, 2, 3, 5] console .log (fn2 (data)) //=> {list: [1, 2, 3, 5], newItem: 5}
 .as-console-wrapper {max-height: 100% !important; top: 0}
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script> <script> const {lift, append, prop, chain, mergeLeft, applySpec} = R </script>

Este segundo es un poco difícil de manejar, una vez que en línea fn1 . Repite la list de propiedades en dos lugares, y eso siempre me molesta. Pero no tengo una buena solución en este momento.

Varias veces quise una combinación de R.evolve y R.applySpec , que funciona en el exterior como evolve , lo que le permite especificar solo las propiedades que deben cambiar, pero cuyas funciones de transformación se dan en todo el objeto de entrada, y no solo la propiedad correspondiente.

Con algo así, esto podría verse como

 const f3 = evolveSpec ({ list: ({list, newItem}) => [...list, newItem] })

o usando lo anterior:

 const f3 = evolveSpec ({ list: lift (append) (prop ('newItem'), prop ('list')) })

Creo que este podría ser un candidato útil para su inclusión en Ramda.

about 4 years ago · Juan Pablo Isaza Denunciar

0

 const addItem = R.chain ( R.assoc('list') ) ( R.converge(R.append, [R.prop('newItem'), R.prop('list')]) ); const data = { list: [1, 2, 3], newItem: 5 }; console.log(addItem(data));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>

Y he aquí por qué:

Primero, podemos echar un vistazo a cómo se supone que debe verse el addItem actual cuando no está libre de puntos:

 const addItem = x => R.assoc('list') ( R.pipe( R.prop('list'), R.append(R.prop('newItem')(x)) )(x) )(x); console.log(addItem({ list: [1, 2, 3], newItem: 5 }));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>

Toma algunos datos y los usa en tres lugares. Podemos refactorizar un poco:

 const f = R.assoc('list'); const g = x => R.pipe( R.prop('list'), R.append(R.prop('newItem')(x)) )(x) const addItem = x => f(g(x))(x); console.log(addItem({ list: [1, 2, 3], newItem: 5 }));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>

La parte x => f(g(x))(x) puede no ser obvia de inmediato, pero mirando la lista de combinadores comunes en JavaScript , se puede identificar como S_ :

Nombre # Haskell Ramda Santuario Firma
cadena S_³ (=<<)² cadena² cadena² (a → b → c) → (b → a) → b → c

Por lo tanto x => f(g(x))(x) se puede simplificar sin puntos a R.chain(f)(g) .


Esto deja la g que todavía toma un argumento y lo usa en dos lugares. El objetivo final es extraer dos propiedades de un objeto y pasarlas a R.append() , esto se puede expresar más fácilmente (y sin puntos) con R.converge() como:

 const g = R.converge(R.append, [R.prop('newItem'), R.prop('list')]);

Sustituyendo la f y g de nuevo da

 const addItem = R.chain ( R.assoc('list') ) ( R.converge(R.append, [R.prop('newItem'), R.prop('list')]) );
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda