回答の最後にある拡張メソッドを使用GroupConsecutive
すると、次のことができます。
List<Day> days = new List<Day>
{
new Day { Name = "Sunday", Hours= "8am - 9pm" },
new Day { Name = "Monday", Hours= "8am - 10pm" },
new Day { Name = "Tuesday", Hours= "8am - 10pm" },
new Day { Name = "Wednesday", Hours= "8am - 10pm" },
new Day { Name = "Thursday", Hours= "9am - 10pm" },
new Day { Name = "Friday", Hours= "8am - 11pm" },
new Day { Name = "Saturday", Hours= "8am - 11pm" },
};
var query = from g in days.GroupConsequtive(d => d.Hours)
select new {
Name = g.Count() == 1 ? g.First().Name :
String.Format("{0}-{1}", g.First().Name.Substring(0, 3), g.Last().Name.Substring(0, 3)),
Hours = g.Key
};
結果の列挙:
foreach (var item in query)
Console.WriteLine("{0} {1}", item.Name, item.Hours);
出力:
Sunday 8am - 9pm
Mon-Wed 8am - 10pm
Thursday 9am - 10pm
Fri-Sat 8am - 11pm
連続グループ化の拡張方法:
public static class LazyExtensions
{
public static IEnumerable<IGrouping<TKey, TElement>> GroupConsecutive<TKey, TElement>(
this IEnumerable<TElement> source, Func<TElement, TKey> keySelector)
{
if (!source.Any())
yield break;
var comparer = Comparer<TKey>.Default;
Grouping<TKey, TElement> group = null;
foreach (var item in source)
{
var key = keySelector(item);
if (group == null)
group = new Grouping<TKey, TElement>(key);
if (comparer.Compare(group.Key, key) != 0)
{
yield return group;
group = new Grouping<TKey, TElement>(key);
}
group.Elements.Add(item);
}
yield return group;
}
private class Grouping<TKey, TElement> : IGrouping<TKey, TElement>
{
public Grouping(TKey key)
{
Key = key;
Elements = new List<TElement>();
}
public List<TElement> Elements { get; private set; }
public TKey Key { get; private set; }
public IEnumerator<TElement> GetEnumerator()
{
return Elements.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
使い方?グループ化 (IGrouping インターフェイスを実装するカスタム クラス) を作成し、同じキー値を持つ連続する要素をそのグループに追加します。新しいキー値が到着すると、グループ化が返されます。したがって、すべてのシーケンスは連続するキー値によってグループ化されます。