0. はじめに
24.10.16追記
本家のSelectMany
で対応可能でした。(@htsignさんありがとうございます)
ですので、以下は読まなくても良いですが、自戒を込めて晒したままにしておきます
追記 終わり
Freeradicalの中の人、yamarahです。
CollectionのCollectionを網羅したいときってないですか? という話です。
ソースの1つの連続した列挙を、受け取り時に複数のコレクションに分割登録したけど、何らかの理由で全部のデータを舐めたいことが、たまによくある。
1. 状況例
public class Shop
{
public List<string> Items = [];
}
があって、
List<Shop> shops;
に含まれるItem
を連続的に処理したい。
例えばあるItem
が、どのShop
にも含まれないことを検証する場合とか。
LINQを使って普通に書くと、こんな感じ。
var exist = shops.shops(x => x.Items).Any(x => x.Contains("ずんだもち"));
Any
とContains
が被っているのに、ちょっとモヤっとします。
Contains
をAny
で書き換えると、モヤモヤがはっきりと見えます。
var exist = shops.Select(x => x.Items).Any(x => x.Any(x => x == "ずんだもち")))
こうではなく、一つながりの列挙として処理したいという欲求があります。
2. 作ってみた
public static class LinqPlus
{
public static IEnumerable<TResult> Expand<TResult>(this IEnumerable<IEnumerable<TResult>> source)
{
foreach (var collection in source)
{
foreach (var item in collection)
{
yield return item;
}
}
}
}
これで、
var exist = shops.Select(x => x.Items).Expand().Contains("ずんだもち")
と書けてスッキリ!
名前はConcat
でも良いのかもしれないけど、本家と混乱しそうなので仮にExpand
としました。
3. 懸念
ひょっとして、私が知らないだけで本家に同機能の拡張メソッドがあったりしないですよね・・・