2016-10-20 9 views
6

ベクトルからx番目と最後の要素を取り出して連結したいと考えています。私は、次のコードを持っている:Rustで2つのスライスを連結するにはどうすればよいですか?

fn main() { 
    let v = (0u64 .. 10).collect::<Vec<_>>(); 
    let l = v.len(); 
    vec![v.iter().take(3), v.iter().skip(l-3)]; 
} 

これは私にエラーを与える

error[E0308]: mismatched types 
--> <anon>:4:28 
    | 
4 |  vec![v.iter().take(3), v.iter().skip(l-3)]; 
    |       ^^^^^^^^^^^^^^^^^^ expected struct `std::iter::Take`, found struct `std::iter::Skip` 
<anon>:4:5: 4:48 note: in this expansion of vec! (defined in <std macros>) 
    | 
    = note: expected type `std::iter::Take<std::slice::Iter<'_, u64>>` 
    = note: found type `std::iter::Skip<std::slice::Iter<'_, u64>>` 

どのように私は1, 2, 3, 8, 9, 10の私のvecを得るのですか?私は錆1.12を使用しています。

答えて

3

あなたはskip()collect()編の結果とtake()extend()それらの結果をcollect()必要があります。

let mut p1 = v.iter().take(3).collect::<Vec<_>>(); 
let p2 = v.iter().skip(l-3); 

p1.extend(p2); 

println!("{:?}", p1); 

編集:Neikosが言ったように、あなたもskip()の結果を収集する必要はありません。 extend()は、IntoIteratorSkipのように、Iterator)を実装する引数を受け入れます。

編集2:あなたの番号は少し離れていますが、

let v = (1u64 .. 11).collect::<Vec<_>>(); 

Rangeが閉じ、左と右開きされているので、次のよう1, 2, 3, 8, 9, 10を得るために、あなたはvを宣言する必要があります。

+0

ありがとう。 '<_>'は「型を推測してください」のような意味ですか? –

+2

'skip'を' extend'として取得する必要はありません。 – Neikos

+0

@TheUnfunCatはい、 '_'は型プレースホルダーです。 – Neikos

9

まず、初期シーケンス定義が間違っています。あなたが出力として1, 2, 3, 8, 9, 10たいと言うので、それは次のようになります。あなたはスライスを連結する

let v = (1u64 .. 11).collect::<Vec<_>>(); 

次に、あなたが言う、それでは、実際にスライス使ってみましょう:この

let head = &v[..3]; 
    let tail = &v[l-3..]; 

をそれは本当にあなたが一番好きなアプローチに近いのです。あなたは...収集し、その後、イテレータに

let v2: Vec<_> = head.iter().chain(tail.iter()).collect(); 

をチェーンを、それらのスライスを回す...またはVECを作り、直接スライスでそれを拡張...

let mut v3 = vec![]; 
    v3.extend_from_slice(head); 
    v3.extend_from_slice(tail); 

することができます...かCOUを...

let mut v4: Vec<u64> = vec![]; 
    v4.extend(head); 
    v4.extend(tail); 

を(専門で、将来的に同等になるだろうが、私はそれだけではまだとして効率的だとは思わない)、より一般的なイテレータを使用して拡張します...かループ内でVec::with_capacitypushを使用するか、チェーンイテレータを使用しますが、extendを使用します...しかし、私はで停止する必要があります。ポイント。

完全なサンプルコード:

fn main() { 
    let v = (1u64 .. 11).collect::<Vec<_>>(); 
    let l = v.len(); 

    let head = &v[..3]; 
    let tail = &v[l-3..]; 

    println!("head: {:?}", head); 
    println!("tail: {:?}", tail); 

    let v2: Vec<_> = head.iter().chain(tail.iter()).collect(); 
    println!("v2: {:?}", v2); 

    let mut v3 = vec![]; 
    v3.extend_from_slice(head); 
    v3.extend_from_slice(tail); 
    println!("v3: {:?}", v3); 

    // Explicit type to help inference. 
    let mut v4: Vec<u64> = vec![]; 
    v4.extend(head); 
    v4.extend(tail); 
    println!("v4: {:?}", v4); 
} 
+1

' extend() 'はすぐに' extend_from_slice() 'に特化する必要があります。それは数日前にマージされました:[Specialize Vec :: Vec :: extend_from_sliceに拡張する](https://github.com/rust-lang/rust/pull/37094)。 – ljedrz

+0

安定したリリースは... 9週間離れていますか?私が言ったように、まだまだ* –

+1

'let v =(1u64 .. 11).collect :: >();' booo。 'let v:Vec =(1..11).collect();' yaaay – Shepmaster

5

だけのスライスのスライスに.concat()を使用します。

fn main() { 
    let v = (0u64 .. 10).collect::<Vec<_>>(); 
    let l = v.len(); 
    let first_and_last = [&v[..3], &v[l - 3..]].concat(); 
    println!("{:?}", first_and_last); 
    // The output is `[0, 1, 2, 7, 8, 9]` 
} 

これは、新しいベクトルを作成し、それがスライスの任意の数で動作します。

(Playground link)

+0

私は新しいAPIの学習が大好きです! – Shepmaster

関連する問題