2010-09-29 3 views
5

Ich habe ein Array von Elementen wie in Javascript folgt:Javascript natürliche Art Array/Objekt und halten die Verbindung zum Index

var users = Array(); 

users[562] = 'testuser3'; 
users[16] = 'testuser6'; 
users[834] = 'testuser1'; 
users[823] = 'testuser4'; 
users[23] = 'testuser2'; 
users[917] = 'testuser5'; 

Ich brauche das Array zu sortieren, die folgende Ausgabe zu erhalten:

users[834] = 'testuser1'; 
users[23] = 'testuser2'; 
users[562] = 'testuser3'; 
users[823] = 'testuser4'; 
users[917] = 'testuser5'; 
users[16] = 'testuser6'; 

Beachten Sie, wie es nach dem Wert des Arrays sortiert ist und dass die Assoziation von Wert zu Index beibehalten wird, nachdem das Array sortiert wurde (das ist kritisch). Ich habe nach einer Lösung gesucht, versucht, es zu schaffen, aber ich habe eine Wand getroffen.

Übrigens ist mir bewusst, dass dies technisch kein Array ist, da dies bedeuten würde, dass die Indizes immer 0 bis n durchlaufen, wobei n + 1 die Zählnummer ist, die n fortsetzt. Wie auch immer Sie es definieren, die Anforderung an das Projekt ist immer noch dieselbe. Auch, wenn es einen Unterschied macht, verwende ich nicht jQuery.

Antwort

2

die Ideen aus den Kommentaren benutzen, kam ich mit der folgenden Lösung. Die NaturalSort-Funktion habe ich bei Google gefunden und ich habe sie modifiziert, um ein mehrdimensionales Array zu sortieren. Im Grunde habe ich das Benutzer-Array zu einem mehrdimensionalen Array gemacht, wobei der erste Index die Benutzer-ID und der zweite Index der Benutzername ist. Also:

users[0][0] = 72; 
users[0][1] = 'testuser4'; 
users[1][0] = 91; 
users[1][1] = 'testuser2'; 
users[2][0] = 12; 
users[2][1] = 'testuser8'; 
users[3][0] = 3; 
users[3][1] = 'testuser1'; 
users[4][0] = 18; 
users[4][1] = 'testuser7'; 
users[5][0] = 47; 
users[5][1] = 'testuser3'; 
users[6][0] = 16; 
users[6][1] = 'testuser6'; 
users[7][0] = 20; 
users[7][1] = 'testuser5'; 

I sortiert dann das Array die folgende Ausgabe zu erhalten:

users_sorted[0][0] = 3; 
users_sorted[0][1] = 'testuser1'; 
users_sorted[1][0] = 91; 
users_sorted[1][1] = 'testuser2'; 
users_sorted[2][0] = 47; 
users_sorted[2][1] = 'testuser3'; 
users_sorted[3][0] = 72; 
users_sorted[3][1] = 'testuser4'; 
users_sorted[4][0] = 20; 
users_sorted[4][1] = 'testuser5'; 
users_sorted[5][0] = 16; 
users_sorted[5][1] = 'testuser6'; 
users_sorted[6][0] = 18; 
users_sorted[6][1] = 'testuser7'; 
users_sorted[7][0] = 12; 
users_sorted[7][1] = 'testuser8'; 

Der Code, dies zu tun ist unten:

function naturalSort(a, b) // Function to natural-case insensitive sort multidimensional arrays by second index 
{ 

    // setup temp-scope variables for comparison evauluation 
    var re = /(-?[0-9\.]+)/g, 
     x = a[1].toString().toLowerCase() || '', 
     y = b[1].toString().toLowerCase() || '', 
     nC = String.fromCharCode(0), 
     xN = x.replace(re, nC + '$1' + nC).split(nC), 
     yN = y.replace(re, nC + '$1' + nC).split(nC), 
     xD = (new Date(x)).getTime(), 
     yD = xD ? (new Date(y)).getTime() : null; 
    // natural sorting of dates 
    if (yD) 
     if (xD < yD) return -1; 
     else if (xD > yD) return 1; 
    // natural sorting through split numeric strings and default strings 
    for(var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++) { 
     oFxNcL = parseFloat(xN[cLoc]) || xN[cLoc]; 
     oFyNcL = parseFloat(yN[cLoc]) || yN[cLoc]; 
     if (oFxNcL < oFyNcL) return -1; 
     else if (oFxNcL > oFyNcL) return 1; 
    } 
    return 0; 
} 

// Set values for index 
    var users = Array(); 
    var temp = Array(); 

    users.push(Array('72', 'testuser4')); 
    users.push(Array('91', 'testuser2')); 
    users.push(Array('12', 'testuser8')); 
    users.push(Array('3', 'testuser1')); 
    users.push(Array('18', 'testuser7')); 
    users.push(Array('47', 'testuser3')); 
    users.push(Array('16', 'testuser6')); 
    users.push(Array('20', 'testuser5')); 

// Sort the array 
    var users_sorted = Array(); 
    users_sorted = users.sort(naturalSort); 
+0

Hey, ich bin froh, dass du eine Antwort gefunden hast, die funktioniert, aber ich ermutige dich, einen kurzen Blick auf [meine Antwort] zu werfen (http://stackoverflow.com/questions/3824392/javascript-natural-sort-array-object) -und-maintain-index-association/3824938 # 3824938) (Ich war ein bisschen zu spät zum Spiel!) oben. String-Vergleich ist in JavaScript integriert, und Sie können feststellen, dass es insgesamt eine sauberere Lösung ist. – s4y

+0

Sie sollten auch in Array-und Objektliterale schauen (ich erwähne sie nur kurz in meiner Antwort). Du könntest das Array 'users' in deinem Beispielcode viel schneller erstellen: 'var users = [['72', 'testuser4'], ['91', 'testuser2'], ...]' – s4y

+0

Danke für die Köpfe, es sieht sauberer aus. Unterstützt es jedoch die natürliche Fallsortierung? Das hat meinen Code ein wenig schlampiger gemacht. – user396404

3

Sie können solche Arrays in Javascript nicht sortieren. Ihre beste Wette ist, eine Karte für Auftrag zu machen.

order = new Array(); 
order[0] = 562; 
order[1] = 16; 
order[2] = 834; 
order[3] = 823; 
order[4] = 23; 
order[5] = 917; 

Auf diese Weise können Sie eine beliebige Reihenfolge unabhängig von den Schlüsseln im ursprünglichen Array haben. Um Ihr Array zu sortieren, verwenden Sie eine benutzerdefinierte Sortierfunktion .

order.sort(function(a, b) { 
    if (users[a] < users[b]) return -1; 
    else if (users[a] > users[b]) return 1; 
    else return 0; 
}); 

for (var i = 0; i < order.length; i++) { 
    // users[ order[i] ] 
} 

[Demo]

22

Die Reihenfolge der Elemente eines Arrays wird durch den Index definiert wird. Also selbst wenn Sie die Werte in einer anderen Reihenfolge angeben, werden die Werte immer in der Reihenfolge ihrer Indizes gespeichert werden und nicht definierten Indizes sind undefined:

> var arr = []; 
> arr[2] = 2; 
> arr[0] = 0; 
> arr 
[0, undefined, 2] 

Nun, wenn Sie das Paar von Index und Wert speichern möchten, Sie werden eine andere Datenstruktur benötigen, vielleicht ein Array von Array wie folgt:

var arr = [ 
    [562, 'testuser3'], 
    [16, 'testuser6'], 
    [834, 'testuser1'], 
    [823, 'testuser4'], 
    [23, 'testuser2'], 
    [917, 'testuser5'] 
]; 

Dies kann mit dieser Vergleichsfunktion sortiert werden:

function cmp(a, b) { 
    return a[1].localeCompare(b[1]); 
} 
arr.sort(cmp); 

Das Ergebnis ist dieser Array:

[ 
    [834, 'testuser1'], 
    [23, 'testuser2'], 
    [562, 'testuser3'], 
    [823, 'testuser4'], 
    [917, 'testuser5'], 
    [16, 'testuser6'] 
] 
0

Array.prototype.sort() nimmt eine optionale benutzerdefinierte Vergleichsfunktion - also wenn Sie Dump alle Ihre users in ein Array auf diese Weise [ [562, "testuser3"], [16, "testuser6"] ... etc.]

Dann sort dieses Array mit der folgenden Funktion :

function(comparatorA, comparatorB) { 
    var userA = comparatorA[1], userB = comparatorB[1] 
    if (userA > userB)  return 1; 
    if (userA < userB)  return -1; 
    if (userA === userB) return 0; 
} 

Dann erstellen Sie Ihr users Objekt neu. (Was Sie Ihre Sortierung verlieren wird.) Oder halten Sie die Daten in der neu sortierten Array-Array, wenn das für Ihre Anwendung funktioniert.

7

Wenn ich die Frage richtig verstanden habe, verwenden Sie Arrays in einer Weise, die sie nicht verwendet werden sollen.In der Tat lehrt der Initialisierungsstil

// Don't do this! 
var array = new Array(); 
array[0] = 'value'; 
array[1] = 'value'; 
array[2] = 'value'; 

falsche Dinge über die Art und den Zweck von Arrays. Ein Array ist eine geordnete Liste von Elementen, die von Null aufwärts indiziert werden. Der richtige Weg, um ein Array zu erstellen, ist mit einem Arrayliteral:

var array = [ 
    'value', 
    'value', 
    'value' 
] 

Die Indizes werden impliziert basierend auf der Reihenfolge der Elemente festgelegt sind. Erstellen eines Arrays und Einstellung users[562] = 'testuser3'impliziert, dass es mindestens 562 andere Benutzer in der Liste gibt, und dass Sie einen Grund haben, nur das 563. zu dieser Zeit zu kennen.

In Ihrem Fall ist der Index Daten, und ist nicht die Reihenfolge der Elemente in der Gruppe. Was Sie suchen ist, eine Karte oder einen Wörterbuch, dargestellt in JavaScript von einem Ebene Objekt:

var users = { 
    562: 'testuser3', 
    16: 'testuser6', 
    834: 'testuser1', 
    823: 'testuser4', 
    23: 'testuser2', 
    917: 'testuser5' 
} 

Jetzt ist Ihr Satz keinen Auftrag hat, aber sinnvollen Schlüssel hat. Von hier aus können Sie galambalazs's advice folgen eine Reihe der Schlüssel des Objekts zu erstellen:

var userOrder; 
if (typeof Object.keys === 'function') { 
    userOrder = Object.keys(users); 
} else { 
    for (var key in users) { 
     userOrder.push(key); 
    } 
} 

... es dann sortieren:

userOrder.sort(function(a, b){ 
    return users[a].localeCompare(users[b]); 
}); 

Here's a demo

+0

@Gumbo Ich stimme zu! Worin unterscheidet sich meine Antwort? – s4y

+0

Macht nichts. Irgendwie dachte ich, du versuchst die Eigenschaften eines Objekts zu sortieren. – Gumbo

1

I Karte verwenden würde einmal um ein neues Array von Benutzern zu erstellen, dann ein zweites Mal, um die gewünschte Zeichenfolge aus dem neuen Array zurückzugeben.

var users= []; 
users[562]= 'testuser3'; 
users[16]= 'testuser6'; 
users[834]= 'testuser1'; 
users[823]= 'testuser4'; 
users[23]= 'testuser2'; 
users[917]= 'testuser5'; 

var u2= []; 
users.map(function(itm, i){ 
    if(itm){ 
     var n= parseInt(itm.substring(8), 10); 
     u2[n]= i; 
    } 
}); 
u2.map(function(itm, i){ 
    return 'users['+itm+']= testuser'+i; 
}).join('\n'); 

/*returned value: (String) 
users[834]= testuser1 
users[23]= testuser2 
users[562]= testuser3 
users[823]= testuser4 
users[917]= testuser5 
users[16]= testuser6 
*/ 

Wenn Sie Lücken vermeiden möchten. Verwenden Sie einen einfachen Filter am Ausgang

u2.map(function(itm, i){ 
    return 'users['+itm+']= testuser'+i; 
}).filter(function(itm){return itm}).join('\n'); 
1

Sparse-Arrays in der Regel buchstabieren Probleme. Du bist besser dran sparende Schlüssel-Wert-Paare in einem Array als Objekte (diese Technik ist auch gültig JSON):

users = [{ 
    "562": "testuser3" 
},{ 
    "16": "testuser6" 
}, { 
    "834": "testuser1" 
}, { 
    "823": "testuser4" 
}, { 
    "23": "testuser2" 
}, { 
    "917": "testuser5" 
}]; 

Wie vorgeschlagen Sie eine for-Schleife verwenden, können die Sortierfunktion auf das Array abzubilden.

Verwandte Themen