2017-05-22 23 views
0

テーブルをソート可能な列で埋めるために使用されるオブジェクトの観測可能な配列があります。0を常に最後に並べ替え(昇順と降順の並べ替えの両方で)可観測配列を並べ替えます。

私のソート機能は完璧に動作し、以下の簡素化に基づいています。

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

これは、昇順およびソート降順0 最後両方の常に場所の値に変更することができどのように?

ソートされていない値:3,1,2,2,0,1,3,0

降順:3,3,2,2,1,1,0,0

昇順:1,1,2 、2,3,3,0,0

答えて

1

の下に更新されたスクリプトを参照してください問題だから1つの値が常に最後になり、スタックオーバーフローの前に何回も返答されています。 (example

もっと面白いことをするには、ノックアウトがテーブルにもたらすことができるものを探求したいかもしれません。

それは、computedソート方法やソート項目のcomputed配列を含めることは素晴らしいかもしれないので、2つの方法の間に1つのチェックボックススワップ:

// 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

この回答ありがとうございます作業のスニペットを見るには非常に便利です。私はES6をサポートしていないターゲットブラウザのためにjavascriptのいくつかをリファクタリングする必要がありますが、あなたの一般的なアイデアをあまり使用しません! – Drummad

2

私はあなただけlがゼロであれば、それは1を返すようにする必要がありだと思う - 私はメインを信じる

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; 
 
});

+0

は答えをいただき、ありがとうございます。それは正しい軌道にあるようですが、最新の編集で私は注文を受けています:昇順の0,1,2,3,4。 – Drummad

+0

ああ、私が上昇していたのを忘れてしまったのですが、再び上がります。あなたはおそらくちょっとだけifsをきれいにすることができるでしょうが、それはちょうどあなたにアイデアを与えることです – Pete

+0

おかげで再び良い答えを投稿する時間を取ってピート。あなたのロジックは間違いなく私を助けましたが、残念ながら私にとっては完全に機能していないようです。 – Drummad

関連する問題