2013-07-25 9 views
6

Diciamo che ho:estrarre gli elementi da array (slice) x ma continuano dall'inizio se fine viene raggiunto

var array = [0,1,2,3,4,5,6,7,8,9] 

mi definisco:

var itemsToExtract = 5 
var startindex = 7 
var direction = "forward" 

Voglio essere in grado di fare:

array.someMethod(startindex, itemsToExtract, direction) 

e ottenere

[7,8,9,0,1] 

Voglio anche che funzioni all'indietro, se imposto la direzione verso "indietro" (affettare da destra verso sinistra).

Non ero troppo pigro e ho cercato qualcosa di già, vedi qui: http://jsfiddle.net/MkNrr/

sto cercando qualcosa di "più ordinato", se c'è, è anche lì un nome per questo metodo, si tratta di un problema noto?

Contesto: Sto cercando di creare un caricatore sequenziale di immagini pre (caricare un'immagine (src) dopo l'altro) da utilizzare in una galleria di immagini. Forse esiste già una tale libagione?

risposta

0

La sua non è molto, ma guarda bene JS Bin:

function overSlice(arr, start, count, dir){ 
    if(dir==='backward'){ 
     arr = arr.reverse(); 
     start = arr.length-start-1; 
    } 
    var lastIndex = start+count; 
    return arr.slice(start, lastIndex>arr.length?arr.length: lastIndex) 
    .concat(arr.slice(0, lastIndex>arr.length?lastIndex-arr.length: 0)); 
} 

var arr = [0,1,2,3,4,5,6,7,8,9]; 
alert(overSlice(arr,7,5,'backward')); 
0

Basta creare copia della matrice e aggiungere l'array originale fino a quando non è abbastanza lungo:

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
var start = 7 
var count = 5 
var tmparr = arr 

while (tmparr.length < start + count) { 
    tmparr = tmparr.concat(arr); 
} 

var result = tmparr.slice(start, start + count); 

alert(result); 
1

Che ne dite di una funzione che restituisce gli array avanti e indietro? In questo modo non hai bisogno di un interruttore. Qualcosa di simile a questo:

function overslice(arr, idx, items) { 

    var fwd = arr.filter(function(v,i){ return i >= idx }).slice(0, items), 
     back = arr.filter(function(v,i){ return i <= idx }).slice(-items); 

    while (fwd.length < items) { 
    fwd = fwd.concat(arr).slice(0, items); 
    } 

    while (back.length < items) { 
    back = arr.concat(back).slice(-items); 
    } 

    return { fwd: fwd, back: back }; 
} 

quindi è possibile utilizzare le cose come:

var array = [0,1,2,3,4,5,6,7,8,9] 
var result = overslice(array, 7, 5); 

console.log(result.fwd, result.back); //=> [7, 8, 9, 0, 1] [3, 4, 5, 6, 7] 
+0

nei suoi jsfiddle 'spettacoli backward' risultato' 7, 6, 5, 4, 3' – rab

+0

E 'solo una semplice inversione in quel caso 'posteriore: back.reverse()' – elclanrs

1

Il mio approccio:

function overslice(array, startindex, count, direction) { 
    var retarray = []; 
    var increment = (direction === 'backward') ? -1 : 1; 

    for(var c=0, i = startindex; c<count; i+=increment, c++){ 
     retarray.push(array[(i + array.length)%array.length]); 
    } 
    return retarray; 
} 

Working fiddle

UPDATE

Un'altra versione utilizzando la variabile count a dettare la direzione utilizzando valori positivi/negativi e con una correzione per consentire l'uso di count maggiore della lunghezza dell'array:

function overslice(array, startindex, count) { 
    var retarray = []; 
    var increment = (count >= 0) ? 1 : -1; 
    count = Math.abs(count); 
    for(var i = startindex, c = 0;c<count;i+=increment, c++){ 
     if(i<0) i= array.length-1; 
     retarray.push(array[i%array.length]); 
    } 
    return retarray; 
} 

Demo fiddle

0

Per filtrare posizioni non valide, aggiungo alcune convalide, senza le quali il codice può essere ancora più breve.

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
var countToExtract = 10 
var whereToBegin = -1 
var direction = "backword" 

function overslice(array, startIndex, count, direction) { 
    var retArray = []; 
    var step = direction == "backword" ? -1 : 1; 
    var startPos = (startIndex + array.length) % array.length; 
    var endPos = (startPos + (count % array.length) * step + array.length) % array.length; 

    for (var i = 0; i < count; i++) { 
     var pos = (startPos + (i * step) % array.length + array.length) % array.length; 
     retArray.push(array[pos]); 
    } 
    return retArray; 
} 

var lampa = overslice(arr, whereToBegin, countToExtract, direction) 

alert(lampa) 

con codice di cui sopra, è possibile:
iniziare da una posizione meno, che conterà di nuovo dall'altra parte.
il conteggio può essere più lungo della lunghezza dell'array, che restituirà i numeri ripetutamente.

0

Ciao prova questo codice.

function myslice(ar , start , count , dir) { 

    dir = dir || 'F'; 

    var out = [] , 
     times = Math.ceil((start + count)/ ar.length ) + 1; 

    while(times--) { 
     [].push.apply(out, ar); 
    } 

    if (dir == 'B') { 
     start = ar.length - start - 1; 
     out = out.reverse() ; 
    } 

    return out.slice(start , start+count); 
} 

myslice ([0,1,2,3,4,5,6,7,8,9] , 7 , 5 , 'B'); 
Problemi correlati