Pregunta

Estoy pensando en particular de cómo mostrar los controles de paginación, cuando el uso de un lenguaje como C# o Java.

Si tengo x los elementos que quiero mostrar en trozos de y por página, cuántas páginas va a ser necesario?

¿Fue útil?

Solución

Encontrar una solución elegante:

int pageCount = (records + recordsPerPage - 1) / recordsPerPage;

Fuente: Número De Conversión, Roland Backhouse, 2001

Otros consejos

La conversión de punto flotante y la espalda parece de una enorme pérdida de tiempo en el nivel del CPU.

Ian Nelson solución:

int pageCount = (records + recordsPerPage - 1) / recordsPerPage;

Se puede simplificar a:

int pageCount = (records - 1) / recordsPerPage + 1;

AFAICS, este no tiene el desbordamiento de error que Brandon DuRette señaló, y debido a que sólo se utiliza una vez, no es necesario almacenar el recordsPerPage especialmente si se trata de una función costosa para capturar el valor de un archivo de configuración o algo.

I. e.esto podría ser ineficiente, si config.fetch_value utiliza una búsqueda de base de datos o algo:

int pageCount = (records + config.fetch_value('records per page') - 1) / config.fetch_value('records per page');

Esto crea una variable que realmente no necesita, lo que probablemente ha (menor de edad) implicaciones para la memoria y es simplemente demasiado escribir:

int recordsPerPage = config.fetch_value('records per page')
int pageCount = (records + recordsPerPage - 1) / recordsPerPage;

Todo esto es una línea, y sólo recoge los datos a la vez:

int pageCount = (records - 1) / config.fetch_value('records per page') + 1;

Para C#, la solución es convertir los valores a un doble (como las Matemáticas.El techo lleva una doble):

int nPages = (int)Math.Ceiling((double)nItems / (double)nItemsPerPage);

En java, usted debe hacer lo mismo con las Matemáticas.ceil().

Esto debe darle lo que usted desea.Usted definitivamente quiere x elementos divididos por y elementos por página, el problema es cuando los números desiguales de llegar, así que si hay una página parcial también queremos añadir una página.

int x = number_of_items;
int y = items_per_page;

// with out library
int pages = x/y + (x % y > 0 ? 1 : 0)

// with library
int pages = (int)Math.Ceiling((double)x / (double)y);

El entero de matemáticas de la solución que Ian siempre es agradable, pero sufre de un desbordamiento de enteros en el error.Suponiendo que las variables son todos int, la solución podría ser reescrito para usar long matemáticas y evitar el error:

int pageCount = (-1L + records + recordsPerPage) / recordsPerPage;

Si records es un long, el error se mantiene.El módulo solución no tiene el bug.

Una variante de Nick Berardi respuesta que evita una rama:

int q = records / recordsPerPage, r = records % recordsPerPage;
int pageCount = q - (-r >> (Integer.SIZE - 1));

Nota: (-r >> (Integer.SIZE - 1)) consiste en el bit de signo de r, que se repite 32 veces (gracias a firmar la extensión de la >> operador.) Este evalúa a 0 si r es cero o negativo, -1 si r es positiva.Así que restar de q tiene el efecto de la adición de 1 si records % recordsPerPage > 0.

Para los registros == 0, rjmunro solución de la da 1.La solución correcta es 0.Dicho esto, si usted sabe que los registros > 0 (y estoy seguro de que todos hemos asumido recordsPerPage > 0), entonces rjmunro solución proporciona resultados correctos y no tiene ninguna de las desbordamiento de los problemas.

int pageCount = 0;
if (records > 0)
{
    pageCount = (((records - 1) / recordsPerPage) + 1);
}
// no else required

Todos el entero soluciones matemáticas van a ser más eficiente que la cualquier de la de punto flotante de soluciones.

En la necesidad de un método de extensión:

    public static int DivideUp(this int dividend, int divisor)
    {
        return (dividend + (divisor - 1)) / divisor;
    }

No se comprueba aquí (desbordamiento, DivideByZero, etc), siéntase libre de añadir, si quieres.Por cierto, para aquellos preocupados por la invocación del método, la sobrecarga de funciones simples, como esto podría ser insertados por el compilador de todos modos, así que no creo que donde sea que se trate.Saludos.

P. S.usted puede encontrar que es útil ser consciente de esto así (se pone el resto):

    int remainder; 
    int result = Math.DivRem(dividend, divisor, out remainder);

Otra alternativa es usar el mod() función (o '%').Si hay un no-cero resto a continuación, incrementar el resultado entero de la división.

Yo hago lo siguiente, controla los desbordamientos:

var totalPages = totalResults.IsDivisble(recordsperpage) ? totalResults/(recordsperpage) : totalResults/(recordsperpage) + 1;

Y usar esta extensión para que si hay 0 resultados:

public static bool IsDivisble(this int x, int n)
{
           return (x%n) == 0;
}

También, para el número de página actual (no preguntó, pero podría ser útil):

var currentPage = (int) Math.Ceiling(recordsperpage/(double) recordsperpage) + 1;

Alternativa para eliminar la ramificación en la prueba de cero:

int pageCount = (records + recordsPerPage - 1) / recordsPerPage * (records != 0);

No estoy seguro si esto va a funcionar en C#, se debe hacer en C/C++.

para C# uso de las Matemáticas.El techo de la función:

var pageCount= Math.Ceiling((double)myList.Count() / recordsPerPage);

Java y el uso de las Matemáticas.Ceil función:

int n = (int) Math.ceil((double)myList.size() / recordsPerPage));

Un método genérico, cuyo resultado se puede iterar sobre puede ser de interés:

public static Object[][] chunk(Object[] src, int chunkSize) {

    int overflow = src.length%chunkSize;
    int numChunks = (src.length/chunkSize) + (overflow>0?1:0);
    Object[][] dest = new Object[numChunks][];      
    for (int i=0; i<numChunks; i++) {
        dest[i] = new Object[ (i<numChunks-1 || overflow==0) ? chunkSize : overflow ];
        System.arraycopy(src, i*chunkSize, dest[i], 0, dest[i].length); 
    }
    return dest;
}

Yo tenía una necesidad similar en el que necesitaba para convertir Minutos a horas y minutos.Lo que he utilizado:

int hrs = 0; int mins = 0;

float tm = totalmins;

if ( tm > 60 ) ( hrs = (int) (tm / 60);

mins = (int) (tm - (hrs * 60));

System.out.println("Total time in Hours & Minutes = " + hrs + ":" + mins);

El siguiente debe hacer de redondeo mejor que las anteriores soluciones, pero a expensas de rendimiento (debido a de punto flotante de cálculo de 0.5*rctDenominator):

uint64_t integerDivide( const uint64_t& rctNumerator, const uint64_t& rctDenominator )
{
  // Ensure .5 upwards is rounded up (otherwise integer division just truncates - ie gives no remainder)
  return (rctDenominator == 0) ? 0 : (rctNumerator + (int)(0.5*rctDenominator)) / rctDenominator;
}

Usted querrá hacer la división de punto flotante, y, a continuación, utilizar la función ceiling, para redondear el valor de a el siguiente número entero.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top