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

142
Views
¿Usando el operador Mod para paginar múltiples matrices?

Tengo una serie de matrices de las que necesito extraer valores según la página que se solicita. A cada página se le debe asignar una combinación única de datos, por ejemplo:

 let numbers = ['One', 'Two'] let fruits = ['Apples', 'Oranges'] let colours = ['Red', 'Green'] let names = ['John', 'Jane']

Ninguno de los arreglos estaría nunca vacío, por lo que el número de páginas disponibles sería la longitud de todos los arreglos multiplicados entre sí (entonces, en este caso, totalPages sería 16

 let totalPages = numbers.length * fruits.length * colours.length * names.length

Para cada página solicitada, necesito devolver un conjunto único de índices para que cada página muestre un grupo diferente de valores y nunca más de uno de cada grupo.

Actualmente tengo for-loops anidados (ejemplo a continuación) pero me preguntaba si hay una forma más ordenada de usar el operador mod o algo así, para no tener que depender de los for-loops porque en algún momento puede que tenga que introducir arreglos adicionales y odio cómo se ven los bucles anidados...

 let page = 4 // The requested page (not zero-based index) let nPage = 1 for(let numberIndex = 0; numberIndex < numbers.length; numberIndex ++) { for(let fruitIndex = 0; fruitIndex < fruits.length; fruitIndex ++) { for(let colourIndex = 0; colourIndex < colours.length; colourIndex ++) { for(let nameIndex = 0; nameIndex < names.length; nameIndex ++) { // If the loop iteration matches the requested page, // return the combination of indexes as array if(page === nPage) { return [numberIndex, fruitIndex, colourIndex, nameIndex] } nPage ++ } } } }

Gracias de antemano por cualquier idea/sugerencia :o)

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Esta es realmente una pregunta de matemáticas/algoritmos (¡que siempre son divertidas!). Entonces, un buen enfoque es ver si puedes descubrir el patrón. Por ejemplo, dadas 3 matrices, [1,2,3,4] , [x,y,z] y [11,12] , espera

 1 x 11 2 x 11 3 x 11 4 x 11 1 y 11 2 y 11 3 y 11 4 y 11 1 z 11 2 z 11 3 z 11 4 z 11 1 x 12 2 x 12 3 x 12 4 x 12 1 y 12 2 y 12 3 y 12 4 y 12 1 z 12 2 z 12 3 z 12 4 z 12

El patrón debería estar claro ahora, es solo contar, como si 1,2,3,...9,10,11...99,100,101... . Pero en el conteo tradicional, todos los dígitos comienzan en 0 y terminan en 10. Mientras que en nuestro ejemplo, el primer dígito comienza en 1 y termina en 4; el segundo dígito comienza en 'x' y termina en 'z', y el tercero comienza en '11' y termina en 12.

Si alguien le pide que encuentre el n-ésimo dígito (desde la derecha) del m-ésimo número decimal de 4 dígitos (por ejemplo, el 3er dígito de 1234 es 2), podría truncar con temp = floor(m / 10 ** (n-1)) , lo que le daría 1234, 123, 12, 1. Entonces temp % 10 daría el último dígito de cada uno: 4, 3, 2, 1.

En nuestro caso, nuestros dígitos no son base 10, por lo que reemplazamos los 10 con los cálculos apropiados:

 let numbers = ['1', '2', '3']; let fruits = ['a', 'b', 'c']; let colours = ['x', 'y', 'z']; let names = ['11', '12', '13']; let getPage = i => [ numbers[i % numbers.length], fruits[Math.floor(i / numbers.length) % numbers.length], colours[Math.floor(i / numbers.length / fruits.length) % colours.length], ]; // print only the first 40 pages, otherwise stackoverflow will truncate the console for (let i = 0; i < 40; i++) console.log(getPage(i).join(' '));

Y si tiene un conjunto dinámico de matrices (por ejemplo, no sabe de antemano cuál de estas matrices usará):

 let numbers = ['1', '2', '3']; let fruits = ['a', 'b', 'c']; let colours = ['x', 'y', 'z']; let names = ['11', '12', '13']; let getPage = (pageI, arrays) => { // `pageCounts[i]` is the # of combinations that can generated from the 1st `i` arrays. let pageCounts = arrays.map((values, j) => arrays .filter((_, k) => k < j) .map(a => a.length) .reduce((a, b) => a * b, 1)); return arrays.map((values, j) => values[Math.floor(pageI / pageCounts[j]) % values.length]); }; // print only the first 40 pages, otherwise stackoverflow will truncate the console for (let i = 0; i < 40; i++) console.log(getPage(i, [numbers, fruits, colours, names]).join(' '));

about 4 years ago · Juan Pablo Isaza Report

0

Creo que un generador cartesiano funcionaría muy bien aquí, ya que le permite calcular cada combinación y detenerse en el valor n-ésimo sin calcular por adelantado. Aquí hay un ejemplo usando una implementación de esta respuesta .

 let numbers = ['One', 'Two'] let fruits = ['Apples', 'Oranges'] let colours = ['Red', 'Green'] let names = ['John', 'Jane'] let totalPages = numbers.length * fruits.length * colours.length * names.length // Function from https://stackoverflow.com/a/44338759 function* cartesian(head, ...tail) { let remainder = tail.length ? cartesian(...tail) : [[]]; for (let r of remainder) for (let h of head) yield [h, ...r]; } function getPage(n) { const combinations = cartesian(numbers, fruits, colours, names); for (let i = 0; i < (n-1) % totalPages; i++) combinations.next(); return combinations.next().value; } // loops back, so 1 is the same as 17 console.log(getPage(1)) console.log(getPage(17))


En una nota al margen, le aconsejaría que refactorice su código usando una matriz en lugar de variables separadas, ya que lo hará más fácil de mantener.

 const pages = [numbers, fruits, colours, names]; const totalPages = pages.length ? pages.reduce((a,b) => a * b.length, 1) : 0; ... function getPage(n) { const combinations = cartesian(...pages); ...
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!