2016-06-29 6 views
3

manchmal habe ich die Aufgabe zu finden, wenn einige verschachtelte Getter innerhalb eines Werts von Getter zurückgegeben hat eine Eigenschaft. classic C++ wäre so etwas wie:Der beste Weg, um die Verschachtelung von geschachtelten Getter Ergebnis innerhalb Getter

for (const auto& label: labels) 
    for (const auto& artist: label.artists()) 
    if (artist.name = "Arcade Fire") 
     return true; 
return false; 

Was ist der beste Weg, dies mit Bereichen zu tun? Ich denke, so etwas wie dies funktionieren kann:

labels| transform (&Label::artists) | join | transform(&Artist::name) | join | find_if_fn([](){/*...*/}) ; 

Aber es ist ziemlich lang, (teilweise, weil statt .member_fn Sie Klasse schreiben muss.? Member_fn Gibt es einen kürzeren Weg, dies zu tun

+0

Keine Antwort, weil ich range-v3 nicht kenne (außer [link] (https://ericnebler.github.io/range-v3/)), aber die innere Schleife im Eingabebeispiel kann durch ersetzt werden std :: find_if, also denke ich, dass nur ein Join benötigt wird, um alle Künstler zu verflachen, damit ihre Namen überprüft werden können. Auch das find_if_fn() Lambda könnte den Namen bekommen, so dass die zweite Transformation nicht mehr benötigt wird, etwas wie 'labels | transform (& Label :: Künstler) | beitreten | find_if_fn ([] (const Künstler & a) {return a.name == "Die Schmiede";}); '. Macht das überhaupt Sinn? – stefaanv

+0

yeah, ich hätte std :: find_if verwenden können, aber in meinem Code bevorzuge ich keine Mischung für und std :: some_alg. – NoSenseEtAl

+0

nur um zu klären, wenn es eine Option zwischen for und :: alg gibt, die ich alg wähle, mag ich einfach nicht, sie zu mischen. – NoSenseEtAl

Antwort

2

ich denke, das:

using namespace ranges; 
auto rng = labels | view::transform(&Label::artists) | view::join; 
return find(rng, "Arcade Fire", &Artist::name) != end(rng); 

den Job in einer ziemlich einfache Art und Weise getan erhält eine view::filter Formulierung.

using namespace ranges; 
auto rng = labels | view::transform(&Label::artists) | view::join | 
    view::filter([](const Artist& a){ return a.name() == "Arcade Fire"; }); 
return !empty(rng); 

Ist ein bisschen wortreicher, hat aber wahrscheinlich ähnliche Leistung. Es ist auch ziemlich klar, wie man es von "Gibt es ein Foo?" Verallgemeinern kann. "Alle Foos zurückgeben"