並び替えたら、100が2より先に来た。JavaScriptは数字を数字として見ていなかった

一覧に「近い順」を足したら、いちばん上に来たのは100kmの場所だった。
でたらめではなく、ちゃんと何かの規則で並んでいた。

スポットの一覧に「近い順」を足した。

手元で三件だけ試したときは、ちゃんと近い順に並んだ。
よし、と思って本番のデータで開いたら、いちばん上に来たのは 100km の場所だった。

その下が 12km で、その下が 2km。
数字が小さい順でも大きい順でもない。
それでも、でたらめではなかった。ちゃんと何かの規則で並んでいる気配があった。

並んでいたのは、辞書の順番だった

紙に書き出してみて、やっと分かった。

100、12、2。
これは数字としてではなく、文字として並べたときの順番だ。

言葉を辞書で引くときのことを思い出すとはやい。
「あい」と「あお」を比べるとき、僕らは一文字目の「あ」を見て、同じだから二文字目に進む。
それと同じことを、機械は数字の並びにもやっていた。

「100」と「12」を比べるとき、まず先頭の「1」と「1」を見る。同じだ。
次に「0」と「2」を見る。0のほうが小さい。
だから「100」が先。

桁数はいっさい関係ない。
文字の並びとして、前から一文字ずつ見ているだけだった。

ややこしいのは、これが「バグ」ではないことだ。
JavaScript の並び替えは、何も指定しないと中身をいったん文字として扱うと決められている。
決められたとおりに、ものすごく正確に動いていた。

比べ方は、こちらが渡すものだった

直し方そのものは一行だった。

並び替えに「どう比べるか」を一緒に渡してやる。
ふたつを受け取って、前のほうが小さければマイナス、大きければプラス、同じならゼロを返す。ただそれだけの小さな決まりごとを書いて渡す。

数字なら、引き算した結果をそのまま返せばいい。
2 と 100 を渡されたら 2 引く 100 でマイナス。だから 2 が先に来る。

書いてしまえば何ということもないのに、僕はこれを渡していなかった。
「並び替えて」とだけ言って、何を基準に並べてほしいのかを伝えていなかった。
伝えなかったぶんは、向こうが勝手に決める。決め方はあらかじめ公表されていて、それが文字として比べる、だった。

指示していないところに自分の期待が勝手に入り込んでいた、という意味では、日付の形が機械によって違っていた話と根っこは同じだった。
こちらが決めきっていない部分には、必ず誰かの決めた既定値が入っている。

数字のふりをした文字が混ざっていた

ここで終わりだと思っていたら、もう一段あった。

比べ方を渡したのに、一部だけ相変わらず変な位置にいる。
中を見たら、距離の値が数字ではなく「12.5」という文字のまま入っていた行があった。

データを外から読み込んでいる箇所で、そこだけ変換を通していなかった。
文字どうしの引き算は、機械にとっては意味をなさない。結果は数でも文字でもない、比べようのないものになる。
比べようがないと言われた並び替えは、そこだけ手をつけずに放置する。だから一部だけ元の位置に残っていた。

値が空っぽの行も同じだった。
空っぽを数として扱おうとした瞬間に、やはり比べようのないものになる。

並び替えの前に、まず値が本当に数字かどうかを確かめる。
数字でなければ数字に直すか、いちばん後ろに送る。
この一手間を入れてから、ようやく最後まで意図どおりに並んだ。

並び替えは、元の一覧を書き換えていた

最後にもうひとつ、これは実害が出るまで気づかなかった。

並び替えは新しい一覧を作って返してくれるものだと、なんとなく思い込んでいた。
実際は、渡した一覧そのものを並べ替える。元の順番は消える。

僕は同じ一覧を、地図の表示にも使い回していた。
リストを近い順に並べた瞬間に、地図側で拾っていた並びも一緒に変わっていて、ピンの番号がリストとずれた。

並び替える前に一覧の複製を作って、複製のほうを並べる。
それだけで直った。

近ごろのブラウザには、元を触らずに並べ替えた結果だけを返してくれるやり方も用意されている。
ただ、古い機種で動かないことがあるので、僕は当面のあいだ複製を作るほうを続けている。

いちばん怖いのは、途中まで合っていること

この不具合が二日ほど残ってしまったのは、試したデータが少なかったからだ。

三件のときは、たまたま桁がそろっていて正しく並んだ。
桁が混ざった瞬間に崩れた。

順番の間違いは、エラーも赤い文字も出ない。
画面はいつもどおり出ていて、ただ並びだけが違う。
誰かに言われるまで気づけない類の壊れ方で、これがいちばん厄介だと思う。

いまは並び替えを書いたら、必ず桁のばらばらな値と、空っぽの行をひとつ混ぜて試すようにしている。
そこで崩れなければ、たぶん本番でも崩れない。

スタンプラリーに挑戦する 行った場所・気になる場所は、現地チェックインでスタンプに残せます。 みんなのコースを見てみる 会員が作ったスポット巡りのコースを都道府県から探せます。自分だけのコースも作れます。 運営者の個人noteも書いています AI活用やサイト運営で気づいたことを、もう少し個人の視点で掘り下げています。

※運営者が個人で書いているnoteです。

技術ブログ一覧へ戻る