2017-05-24 3 views
1

私はユーザーが内部ベクトルから項目を削除するために呼び出すAPIを作成しています。彼らは削除する要素のベクトルを検索する基準を渡します。任意の要素を見つけて削除した場合、私のAPIにブール値を返すようにしたいと思います。erase-remove_ifイディオム - 何かが削除されましたか?

私はerase-remove idiomを使用して、物事をシンプルかつ効率的に保つことを計画しています。私はアイテムが実際に削除されたことを検出するためにすぐに明らかな方法を見ていないのですか?削除する前にベクトルの要素の数を格納し、その値を比較している、私の最高の賭け?ここで

がこのイディオムの一部(未テスト)のサンプルコードです:

std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 

boolean removeMultiples(int multiple) { 
    v.erase(std::remove_if(v.begin(), v.end(), [multiple](int i){return i%multiple == 0;}), v.end()); 
    // return true if anything was removed 
} 
+0

前後のサイズを比較しますか? –

答えて

4

ひとつのアイデアは、std::remove_ifの戻り値を格納すること、およびこのようなeraseを行う前に、容器end()イテレータと比較します:

bool removeMultiples(int multiple) 
{ 
    auto it = std::remove_if(v.begin(), v.end(), [multiple](int i){return i%multiple == 0;}); 
    bool any_change = it != v.end(); 
    v.erase(it, v.end()); 
    return any_change; 
} 
+0

私はそれをハードコーディングする代わりにラムダを取るでしょう。それから、複数の値を削除してください。 – Yakk

+0

@ Yakk、あなたは 'remove_if'述語を意味しますか?もしそうなら、それはおそらくコンテナの型と述語でパラメータ化されたテンプレートでなければなりませんが、私は質問の文脈で答えたいと思っています。 –

0

ファンクションから返される前に、ベクターの初期サイズと現在のサイズをチェックするのはどうですか?

// returns true if element(s) are removed 
bool vectorRemove(std::vector<int>& v, int criterion) 
{ 
    const unsigned int initial_size = v.size(); 
    // implement the logic of removal after criteria check 
    return initial_size != v.size(); 
} 
+0

'? false:true'が重複しているので、単に '!='を使って直接比較を返してください。 –

+0

@πάνταῥεῖ正解、ありがとうございます! – gsamaras

2

アルゴリズムを1行に書く必要はありません。あなたは、例えば、その後

bool removeMultiples(int multiple) 
{ 
    bool success; 

    auto it = std::remove_if(v.begin(), v.end(), [multiple](int i){return i%multiple == 0;}); 

    if ((success = it != v.end())) v.erase(it, v.end()); 

    return success; 
} 
0
template<class C, class F> 
bool remove_some(C&c, F&&f){ 
    using std::begin; using std::end; 
    auto it = std::remove_if(begin(c), end(c), std::forward<F>(f)); 
    bool r = it!=end(c); 
    c.erase(it, end(c)); 
    return r; 
} 

bool removeMultiples(std::vector<int>& f, int multiple) { 
    return remove_some(v, [multiple](int i){return !(i%multiple);}); 
} 

シンプルかつクリーンで書き込むことができます。

関連する問題