Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

242
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!