2015-10-02 11 views
5

私は反復によって見つかったBTreeMapからアイテムを削除したいと思います。BTreeMapからのアイテムの削除を繰り返して見つけました

明白な理由のために反復処理中にアイテムを削除することはできないので、削除するアイテムをベクターに入れます。主な問題は、参照のベクトルを使用することはできませんが、値のベクトルのみを使用できることです。エントリを削除する必要があるすべてのキーをクローンする必要があります(キーにCloneの特性が実装されていると仮定します)。

#![feature(drain)] 
use std::collections::BTreeMap; 

pub fn clean() { 

    let mut map = BTreeMap::<String, i32>::new(); 


    let mut to_delete = Vec::new(); 

    { 
     for (k, v) in map.iter() { 
      if *v > 10 { 
       to_delete.push(k); 
      } 
     } 

    } 

    for k in to_delete.drain(..) { 
     map.remove(k); 
    } 

} 

を、それがコンパイルされるときには、次のエラーを生成します:たとえば、この短いサンプルがコンパイルされません

to_delete.push(k)を変更
src/lib.rs:21:9: 21:12 error: cannot borrow `map` as mutable because it is also borrowed as immutable [E0502] 
src/lib.rs:21   map.remove(k); 
         ^~~ 
src/lib.rs:20:5: 22:6 note: in this expansion of for loop expansion 
src/lib.rs:12:23: 12:26 note: previous borrow of `map` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `map` until the borrow ends 
src/lib.rs:12   for (k, v) in map.iter() { 
            ^~~ 
src/lib.rs:12:9: 16:10 note: in this expansion of for loop expansion 
src/lib.rs:24:2: 24:2 note: previous borrow ends here 
src/lib.rs:4 pub fn clean() { 
... 
src/lib.rs:24 } 

to_delete.push(k.clone())では、このスニペットが正しくコンパイルできます。しかし、削除する各鍵をクローン化する必要がある場合は、非常にコストがかかります。

もっと良い解決策はありますか?

$ rustc --version 
rustc 1.5.0-nightly (65d5c0833 2015-09-29) 
+2

:代わりにマップを維持しようと、私はちょうど新しいものを作成したいです。関連性は[このproto RFC](https://github.com/rust-lang/rfcs/issues/460)ですが、[this one](https://github.com/rust-lang/rfcs/)をチェックしてくださいpull/1254)と[this one](https://github.com/rust-lang/rfcs/pull/1257)も参照してください。 – Shepmaster

+0

@Shepmaster - もちろん、ここのことは範囲がではなく、むしろ範囲 LinearZoetrope

+0

@Jsorああ、私はそれを逃した。私はそれが起こりそうなケースではないと感じているので、実際には粘着性のケースです! – Shepmaster

答えて

1

私はおそらく少し違った方向からこの問題を見るでしょう。私は最終的には、 `BTreeMap`は` FNのドレイン(&mutの自己、レンジ ) `のような方法を得ることができることを望んでいるだろう

use std::collections::BTreeMap; 

pub fn main() { 
    let mut map = BTreeMap::new(); 

    map.insert("thief", 5); 
    map.insert("troll", 52); 
    map.insert("gnome", 7); 

    let map: BTreeMap<_, _> = 
     map.into_iter() 
     .filter(|&(_, v)| v <= 10) 
     .collect(); 

    println!("{:?}", map); // troll is gone 
} 
+0

これは興味深い考えです。 – Teetoo

+1

削除する要素の数と比較したマップのサイズに依存して、これはパフォーマンスの点では明らかではありません。 –

関連する問題