何かを大量に一覧できるページを見てると特定の値でソートをしたいことが時々あります。(金額、参照回数、ブクマ数、コメント数など…)
サイト側にソートする機能が無い時は自分でコンソールなり、ユーザスクリプトでソートしてやります。
商品一覧で安い順にソートする例
<ul id="sec_forsale">
<li>商品A<p class="price"><del>345円</del> 234円</p></li>
<li>商品B<p class="price"><del>2,000円</del> 1,234円</p></li>
<li>商品C<p class="price"><del>60円</del> 56円</p></li>
<li>商品D<p class="price"><del>10円</del> 1円</p></li>
<li>商品E<p class="price"><del>10円</del> 9円</p></li>
<li>商品F<p class="price"><del>50円</del> 5円</p></li>
</ul>
var container = document.querySelector('#sec_forsale');
[].slice.call(container.querySelectorAll('li'))
.map(function(v){
var value = v.querySelector('.price').innerHTML.replace(/<.+>/,'').replace(/\D/g,'') - 0;
return { dom: v, value: value };
})
.sort(function(a,b){ return a.value - b.value; })
.forEach(function(v){ container.appendChild(v.dom); });
補足
-
querySelectorAll()
の戻り値はNodeList
を返し、配列系メソッドが使えないため、[].slice.call()
で配列化しています。ES6に対応していればArray.from()
も使えます。 - map 内では比較用の値をざっくり取り出し数値化しています。
- また次に行う sort ではアルゴリズム上、比較対象を変えた上で1つの値を何度も評価しますので、パースが何度も行われないように要素と数値両方保持する形に持ち替えています。(シュワルツ変換)
- sort内では持ち替えた
.value
の方を参照します。 - このsortでは要素を持った配列の並び替えでしかないため最後のforEachでDOMに反映します。