2017-12-01 10 views
3

私はこの方法を見つけたが、それは、そのような一般的なアクションのためにあまりにも冗長ようだ:錆のベクトルの要素を繰り返す最善の方法は何ですか?

fn double_vec(vec: Vec<i32>) -> Vec<i32> { 
    let mut vec1 = vec.clone(); 
    let vec2 = vec.clone(); 

    vec1.extend(vec2); 

    vec1 
} 

私はJavaScriptでそれだけでarr2 = [...arr1, ...arr1]可能性があることを知っています。

+1

このソリューションでも、それらの '.clone()'のうちの1つだけが必要です。 – trentcl

答えて

5

あなたは、このためにconcatメソッドを使用することができ、それは簡単です:

fn double_vec(v: Vec<i32>) -> Vec<i32> { 
    [&v[..], &v[..]].concat() 
} 

は、残念ながら、我々は明示的にベクトルのスライスをしなければなりません(ここでは&v[..]);それ以外の場合は、結果を必要なサイズに直接割り当ててからコピーを実行するので、この方法は有効です。

4

「ベクターの倍増」は実際には非常に頻繁に行われるものではないため、そのためのショートカットはありません。さらに、Vecの内部の内容は、その操作がどのような操作を実行できるかを変更するため重要です。この具体例では、次のコードは動作します

let x = vec![1, 2, 3]; 

let y: Vec<_> = x.iter().cycle().take(x.len() * 2).collect(); 

println!("{:?}", y); //[1, 2, 3, 1, 2, 3] 

cycle()方法は、アイテムが重複することができるようにIteratorの項目がClone形質を実装することを必要とします。したがって、Vecの項目にCloneが実装されている場合、これは機能します。不変参照(&)はCloneを実装しているため、Vec<&Something>は動作しますが、可変参照(&mut)はCloneを実装していないため、Vec<&mut Something>は機能しません。タイプがCloneを実装していない場合でも、あなたはまだ、その型への参照を複製することができ

注:ウェズリーの答えに

struct Test; 

fn test_if_clone<T: Clone>(_x: T) {} 

fn main() { 
    let x = Test; 

    test_if_clone(x); //error[E0277]: the trait bound `Test: std::clone::Clone` is not satisfied 

    let y = &x; 

    test_if_clone(y); //ok 
} 
4

ビル、あなたはまた、2回の反復可能オブジェクトを接着した後、1をchainを使用することができますその他。以下の例では、私は二度同じVeciter()メソッドを使用します。

let x = vec![1, 2, 3]; 

let y: Vec<_> = x.iter().chain(x.iter()).collect(); 

println!("{:?}", y); //[1, 2, 3, 1, 2, 3] 
+1

おそらく言及する価値のあることは、 'y'の型は' Vec 'ではなく' Vec <{integer> 'です。これは良いソリューションです。なぜなら、内容を複製できないベクターを扱うことができるからです。 –

3

イテレータメソッドは、ベクトルの拡張子がストレートmemcpyよりもはるかに効率が悪い可能性があります。

あなた自身のコードでは、cloneが多すぎます。あなただけのことで、値の入力を再利用することができます

fn double_vec(mut vec: Vec<i32>) -> Vec<i32> { 
    let clone = vec.clone(); 
    vec.extend(clone); 
    vec 
} 

しかし、Vecの性質は、これはあなたがそのクローンを取り除くことに成功しても、コピーを必要とする可能性があるので、あなたは一般的にあまり以上獲得していないことちょうどconcatを使用しています。

concatをスライスに使用すると、事前にVecを事前に割り当ててから、効率的にextend_from_sliceを実行するので、効率的です。しかし、これは、もはや入力としてVecを取ることは特に賢明ではないということを意味する。以下の記述は厳密に柔軟です。

fn double_slice(slice: &[i32]) -> Vec<i32> { 
    [slice, slice].concat() 
} 
関連する問題