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

200
Vistas
¿Cómo calcular la frecuencia relativa de los elementos de la matriz usando Ramda.js?

Tengo una matriz con valores repetidos y quiero obtener la frecuencia relativa (es decir, proporciones) para cada valor repetido.

Me parece natural tratar esto como un procedimiento de 2 pasos:

  1. contar las ocurrencias de cada valor; y
  2. divida esa cuenta por la longitud de la matriz original.

Para realizar el primer paso, podemos usar R.countBy() de ramda.js :

 const R = require("ramda") const myLetters = ["a", "a", "a", "a", "b", "b", "c", "c", "c", "c"] const counted = R.countBy(R.identity)(myLetters) counted // => gives {"a": 4, "b": 2, "c": 4}

Ahora el segundo paso sería dividir counted por la longitud de myLetters :

 counted / R.length(myLetters) // obviously this doesn't work because it's not mapped

Estoy un poco perdido con la forma de mapear esto correctamente. Mi solución torpe actual que no me gusta:

 // 1. manually calculate the length and store to a variable const nvals = R.length(myLetters) // 2. create a custom division function const divide_by_length = (x) => R.divide(x, nvals) // 3. map custom function to `counted` R.map(divide_by_length, counted) // gives {"a": 0.4, "b": 0.2, "c": 0.4}

Aunque esto funciona, tiene que haber una forma más directa con ramda para pasar de counted a {"a": 0.4, "b": 0.2, "c": 0.4} .

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

0

Me gusta mucho el enfoque de Ori Drori, usando el hecho de que ap (f, g) //~> (x) => f (x) (g (x)) . ( chain utilizada para las funciones es la chain (f, g) //~> (x) => f (g (x)) (x) .)

Mi pensamiento inicial fue similar, usando en su lugar lift , que eleva una función que opera en valores para convertirla en una que opera en contenedores de esos valores. Cuando los contenedores son funciones, opera algo como lift (f) (g, h) //~> (x) => f (g (x), h (x)) , aunque es más genérico, como lift (f) es variable, como lo son las funciones que se le proporcionan y, por lo tanto, también la función que genera, por ejemplo, lift (f) (g, h, i, j) //~> (a, b, c) => f (g (a, b, c), h (a, b, c), i (a, b, c), j (a, b, c))

Entonces, de manera muy similar, escribí:

 const frequencies = lift (map) ( pipe (length, flip (divide)), countBy (identity) ) const myLetters = ["a", "a", "a", "a", "b", "b", "c", "c", "c", "c"] console .log (frequencies (myLetters))
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script> <script> const {lift, map, pipe, length, flip, divide, countBy, identity} = R </script>

No obstante, no me queda claro que un enfoque sin puntos ofrezca algún beneficio aquí. No estoy seguro de cuál prefiero, pero este Ramda sin puntos es tan legible para mi mente:

 const frequencies = (letters, total = letters.length) => map (n => n / total) (countBy (identity) (letters) ) const myLetters = ["a", "a", "a", "a", "b", "b", "c", "c", "c", "c"] console .log (frequencies (myLetters))
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script> <script> const {lift, map, pipe, length, flip, divide, countBy, identity} = R </script>

about 4 years ago · Juan Pablo Isaza Denunciar

0

Debe combinar los resultados de contar los elementos de la matriz con la longitud de la matriz.

Puede usar R.ap como el combinador S proporcionándole 2 funciones. La firma del combinador S es S = (f, g) => x => f(x)(g(x)) , donde f y g son funciones.

En tu caso:

f - Crear un mapa curry con dividir por la longitud

g - Crear un objeto de cuentas

 const { ap, pipe, length, divide, __, map, countBy, identity } = R const fn = ap( pipe(length, divide(__), map), // curry a map by divide by length countBy(identity), // create the counts ) const myLetters = ["a", "a", "a", "a", "b", "b", "c", "c", "c", "c"] const counted = fn(myLetters) console.log(counted)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt+Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

about 4 years ago · Juan Pablo Isaza Denunciar

0

Creo que la respuesta de @Scott (segunda solución) me hizo caer algunos centavos.

Si definimos dos funciones auxiliares de forma preventiva para contar y dividir:

 const myCount = R.countBy(R.identity); const myDivideBy = (divisor, arr) => R.map(elem => elem / divisor); // I was missing this part

Entonces podríamos hacer:

 const calcFreq = (arr) => { return R.pipe(myCount, myDivideBy(arr.length))(arr) }

Que es exactamente el procedimiento de 2 pasos que imaginé desde el principio: primero contar, luego dividir.

 calcFreq(myLetters) // gives {"a": 0.4, "b": 0.2, "c": 0.4}

Una publicación relevante: javascript: forma eficiente de dividir una matriz por un valor

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