気温が低い日が増えてきて、本格的に冬到来という感じですね。
無事にタイヤ交換を終えた翌日、雪が降って驚きました。。。
今回のテーマはそんな寒い季節も吹き飛ばすほど心を熱くする(?)「剰余」についてです。
本記事ではまず「剰余」を定義し、その例を見ることで、剰余とは何かを理解します。
次に「同一視」という考え方を用いて「剰余」を考えることで、どのような世界(集合)が出来上がるかをご紹介します。
最後に、これらをJavaScriptのプログラムでどのように用いることができるか、という簡単な例をご紹介します。
本記事での「剰余」の定義は「割り算の余りのこと」とします。
例を見てみましょう。
5 ÷ 2 = 2 余り 1 => 5 を 2 で割ったときの 剰余 は 1
6 ÷ 2 = 3 余り 0 => 6 を 2 で割ったときの 剰余 は 0
このようになります。
それでは次に「同一視」という考え方についてご紹介します。
「同一視する」とはどういうことかというと「どのようなものを “同じもの” とするかのルールを定めること」です。うまくルールを定めることで、それらの本質的な部分に注目して、それらを「グループ分け」することができるようになります。
概念的なものから数字を用いたものまで、例をいくつか見てみましょう。
ミスタードーナツで販売されているドーナツ全てを集めてきます。
ここに、「穴が N個空いているドーナツ を、それぞれ同じドーナツとする」というルールを定めます。
すると、例えば、味に関わらず「ポン・デ・リング」は全て同じドーナツとなり、さらに「オールドファッション」と「ポン・デ・リング」は同じドーナツ、ということになります。(穴が1個だから)
しかし、穴が0個の「カスタードクリーム」と、穴が1個の「ポン・デ・リング」は別のドーナツです。
例 2
0を除いた 整数を全て集めてきます。( …, -2, -1, 1, 2, … )
ここに「A x B > 0 であれば Aと Bは同じとする」というルールを定めます。
すると「(-1) x (-2) = 2 > 0」なので「-1と-2は同じ」「1 x (-2) = -2 < 0」なので「1と-2は異なる」となります。
このルールを定めると、0を除いた 整数の “世界” には実質「-1 , 1」しかなくなります。
表題にあるように、「剰余が同じ数を同一視」してみます。
つまり、「ある数を固定し、その数で割ったときの余りが同じであれば “同じ数” とする」というルールを作ります。
このとき、全体としては「0以上の整数」を考えていることに注意してください。
まず、 2で割った余り を考えます。
すると、「2で割った余り」は「0 か 1」だけなので、この “世界” には実質「0, 1」しかなくなります。
このルールの下で 0と同じ数を一般に「偶数」と呼び、1と同じ数を「奇数」と呼んでいますね。
次に、3で割った余りを考えます。
すると、「3で割った余り」は「0 か 1 か 2」だけなので、この “世界” には実質「0, 1, 2」しかなくなります。0 と同じ数はいわゆる「3の倍数」です。
一般に、0以上の整数 n で割った余りを考えたとき、その世界には 「0, 1, 2, …, n-1」しかなくなります。(n ÷ n の余りは 0 なので、n まで到達すると 0 になります。)
最後に JavaScript を用いたWebサイトのプログラミングにおいて剰余がどのように用いられるか、具体例を1つご紹介します。
まず、JavaScript (その他のプログラミング言語でもだいたい同様ですが)では、% という演算子で剰余が扱えるようになっています。
「定義」の章で扱った例はそれぞれ、
5 % 2 = 1
6 % 3 = 0
といった具合です。
では、これを使ってどのようなことができるでしょうか?
個人的に一番わかりやすいかな、と思う例をご紹介します。
今、Webサイトのメインビジュアル部分に、クロスフェードで画像が切り替わるようなスライダーを実装したいとします。
スライドの枚数は公開後も変動し、3枚〜 の予定です。
HTMLは例えば次のようにします。
<div class="slider">
<div class="slide">スライド1枚目</div>
<div class="slide">スライド2枚目</div>
<div class="slide">スライド3枚目</div>
</div>
CSS は以下のようにします。(本質的な部分のみ掲載します)
あらかじめ opacity: 0; としておいて、is-viewed クラスが付与されると opacity: 1 に変更されるようにしておきます。また、スライドはあらかじめ position: absolute; で重ねておきます。
.slider {
position: relative;
}
.slide {
position: absolute;
top: 0;
left: 0;
opacity: 0;
transition: opacity 1500ms;
}
.slide.is-viewed {
opacity: 1;
}
本題の JavaScript です。
スライドは配列(NodeList)で取得しておいて、剰余を用いて ターゲットの index を更新することで、index がループしてスライドを切り替える、という部分が今回の本題の部分です。
index の更新は setInterval で 3秒に1回行います。
const slider = document.querySelector('.slider');
const slides = document.querySelectorAll('.slide');
// スライドの枚数を取得
const slidesLength = slides.length;
// 表示するスライドの index を保存する変数
let activeIndex = 0;
setInterval(() => {
// 一旦すべてのスライドを非表示
slides.forEach((slide) => {
slide.classList.remove('is-viewed');
});
// =====================================
// ここが本題
// index を更新する
// 剰余を計算することで、 0 --> 1 --> 2 --> 0 --> ... となる
// =====================================
activeIndex = (activeIndex + 1) % slidesLength;
// =====================================
// 該当のスライドを表示
slides[activeIndex].classList.add('is-viewed');
}, 3000)
いかがでしたでしょうか。
ただ使うだけであれば最後の部分だけでも良いかもしれませんが、さまざまな例や、その考え方を理解しておくことで応用も効くようになってくると思います。
考え型自体も面白いですし、ぜひ興味のある方は深掘りしてみていただければと思います。
※ 余談ですが「同一視のルール」はなんでも好きに作って良いわけではなく、「同値関係」といって、厳密には「ルールはこのような性質を満たさないといけない」といった定義もきちんとあります。数学好きの方はぜひ…
山口県生まれ、山口県育ち。超インドアなので外出することは少なめですが、Webを身近に感じていただける技術トピックなどを中心にご紹介できればと思っています。よろしくお願いいたします!
REC.