367 Stimmen

Javascript - Array basierend auf einem anderen Array sortieren

Ist es möglich, ein Array, das wie folgt aussieht, zu sortieren und neu anzuordnen?

itemsArray = [ 
    ['Anne', 'a'],
    ['Bob', 'b'],
    ['Henry', 'b'],
    ['Andrew', 'd'],
    ['Jason', 'c'],
    ['Thomas', 'b']
]

um die Anordnung dieses Arrays anzupassen:

sortingArr = [ 'b', 'c', 'b', 'b', 'a', 'd' ]

Leider habe ich keine IDs, die ich verfolgen könnte. Ich müsste die Priorität der Elemente-Array, um die sortingArr so nah wie möglich entsprechen.

Aktualisierung:

Hier ist die Ausgabe, nach der ich suche:

itemsArray = [    
    ['Bob', 'b'],
    ['Jason', 'c'],
    ['Henry', 'b'],
    ['Thomas', 'b']
    ['Anne', 'a'],
    ['Andrew', 'd'],
]

Haben Sie eine Idee, wie man das machen kann?

633voto

Durgpal Singh Punkte 9633

Einzeilige Antwort.

itemsArray.sort(function(a, b){  
  return sortingArr.indexOf(a) - sortingArr.indexOf(b);
});

Oder noch kürzer:

itemsArray.sort((a, b) => sortingArr.indexOf(a) - sortingArr.indexOf(b));

95voto

georg Punkte 205206

Etwa so:

items = [ 
    ['Anne', 'a'],
    ['Bob', 'b'],
    ['Henry', 'b'],
    ['Andrew', 'd'],
    ['Jason', 'c'],
    ['Thomas', 'b']
]

sorting = [ 'b', 'c', 'b', 'b', 'c', 'd' ];
result = []

sorting.forEach(function(key) {
    var found = false;
    items = items.filter(function(item) {
        if(!found && item[1] == key) {
            result.push(item);
            found = true;
            return false;
        } else 
            return true;
    })
})

result.forEach(function(item) {
    document.writeln(item[0]) /// Bob Jason Henry Thomas Andrew
})

Hier ist ein kürzerer Code, aber er zerstört die sorting Array:

result = items.map(function(item) {
    var n = sorting.indexOf(item[1]);
    sorting[n] = '';
    return [n, item]
}).sort().map(function(j) { return j[1] })

51voto

David Lewis Punkte 802

Wenn Sie die native Array-Sortierfunktion verwenden, können Sie einen benutzerdefinierten Komparator übergeben, der beim Sortieren des Arrays verwendet wird. Der Komparator sollte eine negative Zahl zurückgeben, wenn der erste Wert kleiner als der zweite ist, Null, wenn sie gleich sind, und eine positive Zahl, wenn der erste Wert größer ist.

Wenn ich Ihr Beispiel richtig verstehe, könnten Sie also etwas wie folgt tun:

function sortFunc(a, b) {
  var sortingArr = [ 'b', 'c', 'b', 'b', 'c', 'd' ];
  return sortingArr.indexOf(a[1]) - sortingArr.indexOf(b[1]);
}

itemsArray.sort(sortFunc);

32voto

Don McCurdy Punkte 9234

Fall 1: Ursprüngliche Frage (keine Bibliotheken)

Es gibt viele andere Antworten, die funktionieren :)

Fall 2: Ursprüngliche Frage (Lodash.js oder Underscore.js)

var groups = _.groupBy(itemArray, 1);
var result = _.map(sortArray, function (i) { return groups[i].shift(); });

Fall 3: Array1 so sortieren, als wäre es Array2

Ich vermute, dass die meisten Leute hier auf der Suche nach einem Äquivalent zu PHP's array_multisort kamen (ich tat), so dachte ich, ich würde diese Antwort auch posten. Es gibt ein paar Optionen:

1. Es gibt eine bestehende JS-Implementierung von array_multisort() . Vielen Dank an @Adnan, der in den Kommentaren darauf hingewiesen hat. Es ist allerdings ziemlich groß.

2. Schreiben Sie Ihr eigenes. ( JSFiddle-Demo )

function refSort (targetData, refData) {
  // Create an array of indices [0, 1, 2, ...N].
  var indices = Object.keys(refData);

  // Sort array of indices according to the reference data.
  indices.sort(function(indexA, indexB) {
    if (refData[indexA] < refData[indexB]) {
      return -1;
    } else if (refData[indexA] > refData[indexB]) {
      return 1;
    }
    return 0;
  });

  // Map array of indices to corresponding values of the target array.
  return indices.map(function(index) {
    return targetData[index];
  });
}

3. Lodash.js o Underscore.js (beides beliebte, kleinere Bibliotheken, die sich auf Leistung konzentrieren) bieten Hilfsfunktionen, die dies ermöglichen:

    var result = _.chain(sortArray)
      .pairs()
      .sortBy(1)
      .map(function (i) { return itemArray[i[0]]; })
      .value();

...die (1) das sortArray gruppieren wird in [index, value] Paare, (2) sortieren sie nach dem Wert (Sie können hier auch einen Callback bereitstellen), (3) ersetzen jedes der Paare mit dem Element aus dem itemArray an dem Index, aus dem das Paar stammt.

23voto

Sushruth Punkte 1054

Dies ist wahrscheinlich zu spät, aber, Sie könnten auch eine modifizierte Version des Codes unten in ES6-Stil verwenden. Dieser Code ist für Arrays wie:

var arrayToBeSorted = [1,2,3,4,5];
var arrayWithReferenceOrder = [3,5,8,9];

Der eigentliche Vorgang :

arrayToBeSorted = arrayWithReferenceOrder.filter(v => arrayToBeSorted.includes(v));

Der eigentliche Vorgang in ES5 :

arrayToBeSorted = arrayWithReferenceOrder.filter(function(v) {
    return arrayToBeSorted.includes(v);
});

Sollte zu folgenden Ergebnissen führen arrayToBeSorted = [3,5]

Das Referenzarray wird nicht zerstört.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X