2017-05-22 1 views
0

Ich habe ein beobachtbares Array von Objekten, die zum Füllen einer Tabelle mit sortierbaren Spalten verwendet werden.Observable-Array sortieren, wobei 0 immer die letzte ist (für aufsteigende und absteigende Sortierung)

Meine Sortierfunktion funktioniert perfekt und ist auf der folgenden Vereinfachung basiert:

self.sortTheItems = function() { 
    self.items.sort(function (l, r) { 
     var rslt = l === r ? 0 : l < r ? -1 : 1; 
     return self.sortAscending() ? rslt : -rslt; 
    }); 
} 

Wie das immer Platz Werte des Sortierens 0 geändert werden könnte letzte sowohl für Auf- und Absteigen?

z.B. Unsortiert Werte: 3,1,2,2,0,1,3,0

absteigend: 3,3,2,2,1,1,0,0

Aufsteigend: 1,1,2 , 2,3,3,0,0

Antwort

1

ich die Haupt glauben Problem, so rting ein Wert immer zuletzt, wurde schon oft auf Stapelüberlauf beantwortet. (example)

Um die Dinge interessanter zu machen, möchten Sie vielleicht erkunden, was knockoutjs an den Tisch bringen können.

Es wäre schön, ein computed Sortierungs-Methode umfassen und eine computed Reihe von sortierten Elemente so ein Kontrollkästchen Swaps zwischen zwei Methoden:

// Wraps a sort method in a pre-check 
 
const sortZeroesLast = sorter => (a, b) => { 
 
    // Check both for `0` 
 
    if (a === 0) return 1; 
 
    if (b === 0) return -1; 
 
    // If none is `0`, we can use our regular sorter 
 
    return sorter(a, b); 
 
}; 
 

 
// Regular sort methods 
 
const sortAscending = (a, b) => (a > b ? 1 : a < b ? -1 : 0); 
 

 
const sortDescending = (a, b) => (a < b ? 1 : a > b ? -1 : 0); 
 

 
const VM = function() { 
 
    this.items = ko.observableArray([3, 1, 1, 0, 2, 1, 5]); 
 

 
    // Determine which sort function to use based on `ascending` setting 
 
    this.ascending = ko.observable(false); 
 

 
    const sorter = ko.pureComputed(() => 
 
    sortZeroesLast(this.ascending() ? sortAscending : sortDescending) 
 
); 
 

 
    // Create a computed that updates when the items 
 
    // change, or the ascending direction 
 
    this.sortedItems = ko.pureComputed(() => this.items().sort(sorter())); 
 

 
    this.input = ko.observable(0); 
 
    this.addInput =() => { 
 
    this.items.push(parseFloat(this.input() || 0)); 
 
    }; 
 
}; 
 

 
ko.applyBindings(new VM());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> 
 

 
<label> 
 
    <input type="checkbox" data-bind="checked: ascending"> 
 
    Ascending 
 
</label> 
 

 
<ul data-bind="foreach: sortedItems"> 
 
    <li data-bind="text: $data"></li> 
 
</ul> 
 

 
<input type="number" data-bind="value: input"><button data-bind="click: addInput">add</button>

+0

Vielen Dank für diese Antwort Sehr nützlich, um ein funktionierendes Snippet zu sehen. Ich werde einige der Javascript umgestalten müssen, weil unsere Zielbrowser ES6 nicht unterstützen, aber ich werde Ihre allgemeine Idee auf eine weniger schöne Weise verwenden! – Drummad

2

ich glaube, Sie gerade es 1 machen müssen zurückkehren, wenn l Null - aktualisiert Skript unter

self.items.sort(function(l, r) { 
 
    var rslt, 
 
    isAscending = self.sortAscending(); 
 

 
    if (l === r) { 
 
    rslt = 0; // return 0 if they are equal 
 
    } else if (l === 0) { 
 
    if (isAscending) { 
 
     rslt = -1; // return -1 as this is minused below to make positive 1 (moving things to the back) 
 
    } else { 
 
     rslt = 1; // return 1 to force to end; 
 
    } 
 
    } else if (l > r) { 
 
    rslt = 1; // return 1 if l is greater than r 
 
    } else { 
 
    rslt = -1; // return -1 when l is less than r 
 
    } 
 

 
    return isAscending ? rslt : -rslt; 
 
});
siehe

+0

Dank für die Antwort danken. Es scheint auf dem richtigen Weg zu sein, aber mit dem letzten Schnitt bekomme ich die Reihenfolge: 0,1,2,3,4 für aufsteigende Reihenfolge. – Drummad

+0

Ah, ich habe vergessen, dass es aufsteigend war, dann wird es wieder falsch verwendet, was bedeutet, dass wir -1 für aufsteigende und 0 brauchen - siehe oben. Sie werden wahrscheinlich in der Lage sein, die Wenns ein bisschen aufzuräumen, aber das ist nur, um Ihnen die Idee zu geben – Pete

+0

Nochmals vielen Dank Pete für die Zeit nehmen, um eine gute Antwort zu posten. Deine Logik hat mir definitiv geholfen, aber leider scheint es nicht vollständig für mich zu funktionieren. – Drummad

Verwandte Themen