いろきゅう.jp 〜Programmable maiden〜 Tech side このページをアンテナに追加 RSSフィード

2017-11-19

コンテナから目的の要素を抽出できなくて死亡

| 12:56

struct Doll
{
  int        id;
  std::string suffix;
};

void rozen()
{
  std::vector<int>  favIdList = { 202, 707 };  // ソート済み
  std::vector<Doll> dolls     = { // id でソート済み
    { 101, "dawa-"    },
    { 202, "kashira"  },
    { 303, "desu-"    },
    { 404, "dayo"     },
    { 505, "nanodawa" },
    { 606, "nanoyo"   },
    { 707, "..."      },
  };

  // { 202, "kashira" } と { 707, "..." } のインスタンスを抽出したい!
  std::vector<Doll> favDolls;
}

「favIdList ∩ dolls」 的なことをしたいというか、favIdList を利用して dolls を選択だか射影したいというか、こういう時どーするのがセオリーなんですかねぇ…ってのが未だに良くわからなかったりします。

set_intersection() なんていう積集合を取ってくれるマンマな関数はあるんですけど、favIdList と dolls は型が違うので利用できないという話。仕方ないので idList を for で回し id を一つずつ抽出して equal_range() で dolls を lookup する?…といっても、やはり型が違うので無理ゲー

比較元IDだけを格納した Dollsインスタンス作るのもナシとします

// こんなの
const Dolls src = { id };

bool operator < (const Doll& lv, const Doll& rv)
{
  return lv.id < rv.id;
}

// エラーチェックしろよ!
const Dolls& fav = *std::equal_range(dolls.begin(), dolls.end(), src).first;


dolls を id をキーにした map 作るのもナシとします。ソート済みなのになんでソートするコンテナに入れなきゃならんのか!ダサい!

std::map<int, Doll> map;
std::transform(dolls.begin(), dolls.end(),
  std::inserter(map, map.begin()), [](const Doll& d){
    return std::move(std::make_pair(d.id, d));
});

// だからエラー(ry
const Doll& fav = *map.find(favId);

こうするのがシンプルですかねぇ…。線形感がモリモリ出てダサいけど…

auto itDolls = dolls.begin();
for(int id : favIdList)
{
  itDolls = std::find_if(itDolls, dolls.end(),
    [id](const Doll& d){ return id == d.id; }
  );
  favDolls.push_back(*itDolls++);
}

アルゴリズム関数やらなんやら組み合わせれば自前で創らず標準関数類だけで頑張れそうだけど、良くわからず。 umm......

kikairoyakikairoya 2017/11/19 19:38 https://wandbox.org/permlink/9A3qiaf5rszZM7oh

ir9ir9 2017/11/20 02:53 あーなるほど、ありがとうございます。
comp に lambda ぶち込む発想しか出てきてませんでしたわ… 頭硬い…

トラックバック - http://d.hatena.ne.jp/ir9Ex/20171119/1511063770