Vec::sort() / dedup() / extend() / drain()
| 対応: | Rust 1.0(2015) |
|---|
RustのVecには、並べ替えをする『sort()』『sort_by()』、重複要素を削除する『dedup()』、他のコレクションを結合する『extend()』、範囲を取り出す『drain()』などが用意されています。
構文
// 昇順にソートします(要素がOrdを実装している必要があります) v.sort(); // カスタム比較関数でソートします v.sort_by(|a, b| a.cmp(b)); // 昇順 v.sort_by(|a, b| b.cmp(a)); // 降順 v.sort_by_key(|x| x.len()); // キー関数でソート // 連続する重複要素を削除します(ソート後に使うと全重複を削除できます) v.dedup(); // 別のイテレータの要素をVecの末尾に追加します v.extend([4, 5, 6]); v.extend(other_vec.iter().copied()); // 指定した範囲の要素を取り出し、新しいVecにします let drained: Vec<i32> = v.drain(1..3).collect();
メソッド一覧
| メソッド | 概要 |
|---|---|
| v.sort() | 要素を昇順にソートします(安定ソート)。 |
| v.sort_unstable() | 要素を昇順にソートします(不安定ソート、sort()より高速)。 |
| v.sort_by(|a, b| ...) | 比較クロージャを使ってソートします。 |
| v.sort_by_key(|x| ...) | キー抽出クロージャを使ってソートします。 |
| v.dedup() | 連続する重複要素を削除します。 |
| v.dedup_by_key(|x| ...) | キー関数が等しい連続要素を削除します。 |
| v.extend(iter) | イテレータの全要素をVecの末尾に追加します。 |
| v.drain(range) | 指定範囲の要素をVecから取り出しイテレータとして返します。 |
| v.truncate(n) | 長さをn要素に切り詰めます(余分な要素はドロップします)。 |
| v.retain(|x| ...) | 条件を満たす要素のみを残します。 |
サンプルコード
vec_sort_dedup_extend.rs
fn main() {
// --- sort() と sort_by() ---
let mut nums = vec![3, 1, 4, 1, 5, 9, 2, 6];
nums.sort();
println!("sort(): {:?}", nums); // [1, 1, 2, 3, 4, 5, 6, 9]
nums.sort_by(|a, b| b.cmp(a)); // 降順
println!("sort_by(降順): {:?}", nums); // [9, 6, 5, 4, 3, 2, 1, 1]
// 文字列をキーでソートします
let mut names = vec!["Majima", "Kiryu", "Akiyama", "Saejima"];
names.sort_by_key(|w| w.len()); // 文字列長でソート
println!("sort_by_key(長さ順): {:?}", names);
// --- dedup() ---
let mut v = vec![1, 1, 2, 3, 3, 3, 4, 5, 5];
v.dedup(); // 連続する重複を削除します
println!("dedup(): {:?}", v); // [1, 2, 3, 4, 5]
// sort() + dedup() で全ての重複を削除します
let mut v2 = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
v2.sort();
v2.dedup();
println!("sort + dedup: {:?}", v2); // [1, 2, 3, 4, 5, 6, 9]
// --- extend() ---
let mut base = vec![1, 2, 3];
base.extend([4, 5, 6]);
println!("extend([4,5,6]): {:?}", base); // [1, 2, 3, 4, 5, 6]
let extra = vec![7, 8, 9];
base.extend(extra.iter().copied());
println!("extend(other.iter()): {:?}", base);
// --- drain() ---
let mut v3 = vec![10, 20, 30, 40, 50];
let drained: Vec<i32> = v3.drain(1..3).collect(); // インデックス1〜2を取り出します
println!("drain(1..3): {:?}", drained); // [20, 30]
println!("残り: {:?}", v3); // [10, 40, 50]
// --- retain() ---
let mut v4 = vec![1, 2, 3, 4, 5, 6, 7, 8];
v4.retain(|x| x % 2 == 0); // 偶数のみ残します
println!("retain(偶数): {:?}", v4); // [2, 4, 6, 8]
}
rustc vec_sort_dedup_extend.rs ./vec_sort_dedup_extend sort(): [1, 1, 2, 3, 4, 5, 6, 9] sort_by(降順): [9, 6, 5, 4, 3, 2, 1, 1] sort_by_key(長さ順): ["Kiryu", "Majima", "Akiyama", "Saejima"] dedup(): [1, 2, 3, 4, 5] sort + dedup: [1, 2, 3, 4, 5, 6, 9] extend([4,5,6]): [1, 2, 3, 4, 5, 6] extend(other.iter()): [1, 2, 3, 4, 5, 6, 7, 8, 9] drain(1..3): [20, 30] 残り: [10, 40, 50] retain(偶数): [2, 4, 6, 8]
概要
『sort()』は安定ソート(同値要素の相対順序を保つ)、『sort_unstable()』は不安定ソート(順序保証なし)です。整数や文字列のような単純なソートなら『sort_unstable()』の方が高速です。浮動小数点数(f32/f64)は『Ord』を実装していないため、『sort_by()』と『partial_cmp()』を組み合わせて使う必要があります。
『dedup()』は隣接する重複を削除します。全ての重複を削除したい場合は、先に『sort()』してから『dedup()』を呼び出してください。
『drain()』はVecから要素を取り出しながらイテレータを返します。元のVecから要素が消えるため、所有権を移動させたい場合に便利です。
Vecの生成は『Vec::new() / vec![]』を、要素の追加・削除は『Vec::push() / pop() / insert() / remove()』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。