<Rust 備忘録> 配列
Rust の配列っぽいデータ構造に該当する型の扱いについてのメモ.
- 固定長配列:
[T; N]
(長さN
を型情報として持つ) - スライス:
&[T]
,&mut [T]
(↑上の配列の領域(最初の要素のポインタと長さ)を指す) - 可変長配列:
Vec<T>
Rust では,1番上の型を一般に「配列」と呼んでいるみたいです.
パフォーマンスを気にしなければ,可変長の Vec<T>
が一番使いやすいかもしれません.
Vec<T>
型
初期化
let v = vec![0, 1, 2, 3, 4];
または
let v = Vec::new();
または
let v: Vec<i32> = (0..4).collect();
列長
len
: 長さcapacity
: 容量(確保されたメモリ長)
let mut v = vec![0, 1, 2, 3, 4]; assert_eq!(v.len(), 5); assert_eq!(v.capacity(), 5);
要素へのアクセス
[]
: 通常の index アクセスget
: 安全な index アクセス(Option
型で参照)
let v = vec![0, 1, 2, 3, 4]; assert_eq!(v[2], 2); let g = v.get(2); assert_eq!(g, Some(&2));
first
: 先頭の要素を安全に参照last
: 最後の要素を安全に参照pop
: 最後の要素を安全に取り出す
let fst = v.first(); assert_eq!(fst, Some(&0)); let lst = v.last(); assert_eq!(lst, Some(&4)); let mut v = vec![0, 1, 2, 3, 4]; let lst = v.pop(); assert_eq!(lst, Some(4)); assert_eq!(v, [0, 1, 2, 3]);
要素の追加
push
: 後方に要素を追加insert
: 指定位置に要素を追加
let mut v = vec![0, 1, 2, 3]; v.push(4); assert_eq!(v, [0, 1, 2, 4]); v.insert(3, 3); assert_eq!(v, [0, 1, 2, 3, 4]);
要素の削除
remove
: 指定位置の要素を削除
let mut v = vec![0, 1, 2, 3, 4]; let r = v.remove(2); assert_eq!(r, 2); assert_eq!(v, [0, 1, 3, 4]);
retain
:filter
的なもの
let mut v = vec![0, 1, 2, 3, 4]; v.retain(|&x| x < 3); assert_eq!(v, [0, 1, 2]);
dedup
: 連続する重複要素を削除
let mut v = vec![0, 1, 2, 2, 1]; v.dedup(); assert_eq!(v, [0, 1, 2, 1]); // ソートしておけばすべての重複要素を削除できる v.sort(); v.dedup(); assert_eq!(v, [0, 1, 2]);
その他の操作
swap
: スワップreverse
: 反転sort
: ソート
let mut v = vec![0, 1, 2, 3, 4]; v.swap(2, 3); assert_eq!(v, [0, 1, 3, 2, 4]); v.reverse(); assert_eq!(v, [4, 2, 3, 1, 0]); v.sort(); assert_eq!(v, [0, 1, 2, 3, 4]);
split_at
: 指定位置で2つに分割
let v = vec![0, 1, 2, 3, 4]; let (l, r) = v.split_at(3); assert_eq!(l, [0, 1, 2]); assert_eq!(r, [3, 4]);
配列に map
する
直接はできないので iter
を経由して map
します.
let mut v = vec![0, 1, 2, 3, 4]; let v = v.iter().map(|&x| x * 2).collect::<Vec<i64>>(); assert_eq!(v, [0, 2, 4, 6, 8]);
[T; N]
&[T]
そのうち書きます.