
前々回、前回に決定的な誤り発見。(1.10)をstd::iterのごとくに使用してますが、それはstd::ops::Range でした。共通するお名前で同様な機能のTraitsが実装されているのでイテレータとして練習してしまいました。今回「よく使いそうな奴ら」は気をつけたつもりなので大丈夫か?怪しいケド。
※「やっつけな日常」投稿順 Index はこちら
イテレータとレンジ
イテレータのドキュメントは以下です。
一方レンジのドキュメントは以下です。
内部に定義されたTraitを見ると、共通のお名前でほぼ似た機能多数が提供されています。それでついつい Rangeオブジェクトのメソッドを練習して、イテレータを練習した気になってました。すみません。ただ、前回、前々回と練習したのはどちらも同じような結果を得られる「簡単な奴ら」だったので、大勢に影響ないかと(いいわけ。)
今回練習してみる「奴ら」
今回練習してみるのは、
-
- filter
- map
- enumerate
- cmp
です。どれもよく使いそうな奴らでないかと。1のfilterは与えたクロージャを使い条件に一致するものだけをイテレータから取り出すもの。2のmapは、イテレータから取り出す要素にクロージャを作用させて変換した値を取り出すもの。3のenumerateは、要素だけでなく、取り出す順番のインデックス番号も同時にとりだすもの。最後のcmpは、イテレータ同士を比較するもの。
ソースが以下に。
fn main() {
//filter
let tgt = [1, 2, 3, 4, 5, 6, 7, 8, 9];
print!("filter:");
for item in tgt.iter().filter(|x| (*x % 3) == 0) {
print!(" {}", item);
}
println!();
//map
let tgt1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
print!("map:");
for item in tgt1.iter().map(|x| x * 2) {
print!(" {}", item);
}
println!();
//enumerate
let tgt2 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
print!("enumerate:");
for (idx, item) in tgt2.iter().enumerate() {
print!(" {}={}", idx, item);
}
println!();
//cmp
let tgt3a = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let tgt3b = [1, 2, 3, 4, 5, 6, 7, 8];
let tgt3c = [1, 2, 3, 4, 5, 6, 7, 8, 0];
let tgt3d = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let tgt3e = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
println!("a:b {:?}", tgt3a.iter().cmp(tgt3b.iter()));
println!("a:c {:?}", tgt3a.iter().cmp(tgt3c.iter()));
println!("a:d {:?}", tgt3a.iter().cmp(tgt3d.iter()));
println!("a:e {:?}", tgt3a.iter().cmp(tgt3e.iter()));
}
実機上での実行結果
実機(WSL2 Ubuntu20.04LTS上の Rust)での実行結果が以下に。
filterで「3の倍数だけ取り出せ」と。できてますな。
mapで「倍の値にせよ」と。できてますな。
enumerateで「インデックス番号と要素を同時に取り出せ」と。これもOK。
コンペア結果も、長さが大きい方がGreater、長さが同じで要素も同じならEqual、でも要素が大なりならGreater、短かったら Less と。まあ、なっとくいく結果なんでないかい。

