2013-03-21 16 views
5

Ho un array con dimensioni simili:ordinamento di un array secondo l'ordine di un altro Array

var arr = [ 
    'small', 
    'small', 
    'small', 
    'small', 
    ... 
    'medium', 
    'medium', 
    'medium', 
    'medium', 
    ... 
    'big', 
    'big', 
    ... 
]; 

Ho bisogno riorganizzare questo array secondo questo ordine:

var order = ['small', 'small', 'medium', 'medium', 'big']; 

Così il risultato finisce per essere qualcosa del genere:

var arr = [ 
    'small', 
    'small', 
    'medium', 
    'medium', 
    'big', 

    'small', 
    'small', 
    'medium', 
    'medium', 
    'big' 

    ... 
]; 

Sono a conoscenza di altre domande simili in SO ma non sono riuscito a trovare nulla fino ad ora. Non sono sicuro di come affrontarlo. Stavo pensando che lo dovrebbe fare sort ma per cosa cerco? Sembra semplice ma sono bloccato, non so da dove cominciare. Qualche suggerimento?

+0

Penso che sia necessario mostrare un esempio reale dell'array prima e dopo. Al momento non riesco a vedere cosa rende l'array diviso sui due set che stai mostrando nell'output. – mplungjan

+0

Titolo: 'Ordinamento dell'array con un altro array' Aspetta cosa? –

+0

@Derek: Sentiti libero di modificare, non so come definire meglio questo problema ... – elclanrs

risposta

1

Beh, ho finalmente finito con questa soluzione che funziona:

function orderBy(arr, order) { 
    var result = [], 
     i = 0, len = arr.length, 
     index; 

    while (result.length < len) { 
    index = arr.indexOf(order[i]); 
    result.push(arr[index]); 
    arr.splice(index, 1); 
    i = i >= order.length-1 ? 0 : ++i; 
    } 

    return result; 
} 

Modifica l'array originale ma va bene.

Demo: http://jsbin.com/umizat/1/edit

+0

Mi piacerebbe conoscere l'applicazione del mondo reale di questo – mplungjan

+0

@mplungjan: Ho una griglia in muratura con 3 caselle di diverse dimensioni Per creare una griglia completa (senza buchi o spazi vuoti), le scatole devono seguire un determinato schema (piccolo, piccolo, medio, medio, grande) .Questa è l'idea generale, ho finito per riempire i buchi con una casella di ricerca "disabilitata" invece di affrontare tutti questi problemi – elclanrs

+0

@elclanrs maledettamente, se avessi visto questo prima non avrei passato il tempo a fare il mio violino e la funzione> Jon

3

Basta definire un segnapunti per il metodo di ordinamento. Ecco il tuo codice. Provalo

var init_arr = ['small', 'big', 'big', 'medium']; 

var scorer = { 
    small: 0, 
    medium: 1, 
    big: 2 
} 

// You can use the same array too. I am creating new one. 
var final_arr = init_arr.sort(function(a,b) { 
    return scorer[a]-scorer[b]; 
}); 

alert(final_arr); //small, medium, big, big 

Working Fiddle

+0

Molto bello, migliore del mio +1. – gdoron

+0

@gdoron Sono contento che ti sia piaciuto :) – sachinjain024

+2

Ho paura che questo non sia il risultato desiderato. Guarda l'esempio. –

0

Perché non si crea 3 matrici e dividere i dati in base alle dimensioni, quindi è possibile recuperare i dati in un determinato ordine.

simile;

SMALL[]; 
MEDIUM[]; 
BIG[]; 

for(i,j,k : upto array lengths : i++,j++,k++){ 

    nwArray.add(SMALL[i]); 
    nwArray.add(SMALL[++i]); 
    nwArray.add(MEDIUM[j]); 
    nwArray.add(MEDIUM[++j]); 
    nwArray.add(BIG[k]); 

} 

return newArray; 
0

Il mio approccio sarebbe in loop sulla matrice ordine e tirando fuori elemento fino a quando la matrice è vuota o non ha l'elemento richiesto.

var sorted = []; 
var arr = [ 
    'small', 
    'small', 
    'small', 
    'small', 
    ... 
    'medium', 
    'medium', 
    'medium', 
    'medium', 
    ... 
    'big', 
    'big', 
    ... 
]; 
var order = ['small', 'small', 'medium', 'medium', 'big']; 

out: 
while (true) { 
    for (var i = 0; i < order.length; i++) { 
    var index = arr.indexOf(order[i]); 
    if ((index === -1) or (arr.length === 0)) { 
     break out; 
    } else { 
     var elem = arr.splice(index, 1); 
     sorted.append(elem[0]); 
    } 
} 
1

Questa risposta funziona solo per il caso esatto che hai descritto, cioè dove la lunghezza della matrice è un multiplo di 5 e i valori sono allineati in piccole, medie e grandi e ci sono il doppio di ogni piccolo e medio come grande.

Si può lavorare per qualsiasi array ordinato di valori dove length % 5 == 0, ma i risultati non potrebbe essere vogliono che si desidera:

function reOrder(array) { 
    var result = []; 
    var f = array.length/5; // this must be an integer 
    var t; 

    for (var i=0; i<f; i++) { 
    t = i*2; 
    result.push.call(result, array.slice(t, t+2)); 
    t = f*2 + i*2; 
    result.push.call(result, array.slice(t, t+2)); 
    t = f*4 + i; 
    result.push.call(result, array.slice(t, t+1)); 
    } 
    return result; 
} 

var a = ['s','s','s','s','s','s','m','m','m','m','m','m','b','b','b']; 
alert(reOrder(a)); // s,s,m,m,b,s,s,m,m,b,s,s,m,m,b 
+0

+1 Questo sembra funzionare per il caso che ho descritto, ma è abbastanza casuale, quindi potrebbe non funzionare per una soluzione a lungo termine – elclanrs

0

So che questa domanda è vecchia, e si dispone di una risposta che si sta utilizzando, ma ho voluto offrire questo esempio e JSFiddle per una soluzione che funziona con qualsiasi tipo di modifica che si potrebbe far finire.

Nota qualsiasi elemento rimasto nell'array originale viene aggiunto alla fine del nuovo array e non è escluso. Se non ci sono abbastanza elementi nell'array per soddisfare i requisiti di order, gli elementi mancanti vengono saltati dall'ordine.

Ora, alla funzione:

function mySort(arr, order) { 
    var newAr = []; 
    var orIndex = 0; 
    while(arr.length != 0) { 
     var type = order[orIndex]; 
     var ind = arr.indexOf(type); 
     if(ind != -1) { 
      newAr.push(type); 
      arr.splice(ind, 1); 
     } 
     orIndex++; 
     if(orIndex >= order.length) { 
      orIndex = 0; 
     } 
    } 
    return newAr; 
} 

Quello che fa, è che ci vuole il tuo esempio le matrici di:

var arrTest = [ 
    'small', 
    'small', 
    'small', 
    'small', 
    'small', 
    'small', 
    'small', 
    'small', 
    'medium', 
    'medium', 
    'medium', 
    'medium', 
    'medium', 
    'medium', 
    'medium', 
    'medium', 
    'big', 
    'big', 
    'big', 
    'big', 
]; 
var orderTest = ['small', 'small', 'medium', 'medium', 'big']; 

Ora, è possibile modificare questi tutto quello che volete, ma fa un cerca nel testo, quindi se lo vuoi ordinare, assicurati che sia uguale sia nell'array completo che nell'array dell'ordine. Ora, utilizzare la funzione, si dovrebbe fare:

var sortedArray = mySort(arrTest, orderTest); 

Oppure, per come ho dimostrato nel Fiddle:

alert(mySort(arrTest, orderTest).join('\n')); 

E questo dovrebbe funzionare per qualsiasi situazione che coinvolge i due e l'ordine può facilmente modificabile

Spero che questo aiuti!

Problemi correlati