日記(日記とは言っていない)

https://zenn.dev/23prime に移行しました。

<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]);

その他の操作

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]

そのうち書きます.