ああ、真田丸が終わっちゃった。
面白かったよおおおおお。
来年は一体どうしたらいいんだあ。
var a = new A(); a.Do(); var b = new B(a); b.Do(); // 後片付け b.Cleanup(); a.Cleanup();
A a = null;
B b = null;
try
{
a = new A();
a.Do();
b = new B(a);
b.Do();
}
finally
{
if (b != null)
b.Cleanup();
if (a != null)
a.Cleanup();
}
public class Disposer : IDisposable
{
private readonly Action disposer;
public Disposer(Action disposer)
{
this.disposer = disposer;
}
public void Dispose()
{
disposer();
}
}
var a = new A();
using (new Disposer(() => a.Cleanup()))
{
a.Do();
var b = new B(a);
using (new Disposer(() => b.Cleanup()))
{
b.Do();
}
}
File.WriteAllLines(
outFile,
File.ReadLines(inFile, Encoding.GetEncoding("shift-jis"))
.Select(line => line.Split(','))
.Where(items => int.Parse(items[0]) % 2 != 0)
.Select(items => string.Join(",", items.Select(item => item.Trim()))));
var sb = new StringBuilder();
string line;
using (var sr = new StreamReader(inFile, Encoding.GetEncoding("shift-jis")))
using (var sw = new StreamWriter(outFile))
{
while ((line = sr.ReadLine()) != null)
{
var items = line.Split(',');
sb.Length = 0;
if (int.Parse(items[0]) % 2 != 0)
{
foreach (var item in items)
{
sb.Append(item.Trim()).Append(',');
}
sw.WriteLine(sb.ToString(0, sb.Length - 1));
}
}
}
var query = from person in people
join pet in pets on person equals pet.Owner into gj
from subpet in gj.DefaultIfEmpty()
select new
{
person.FirstName,
PetName = (subpet == null ? String.Empty : subpet.Name)
};
public static class EnumerableEx
{
public static IEnumerable<TResult> OuterJoin<TOuter, TInner, TKey, TResult>
(this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, TInner, TResult> resultSelector,
TInner innerDefaultValue)
{
return outer
.GroupJoin(
inner,
outerKeySelector,
innerKeySelector,
(o, i) => new { Out = o, Ins = i.DefaultIfEmpty(innerDefaultValue) })
.SelectMany(g => g.Ins, (g, i) => resultSelector(g.Out, i));
}
}
static void Main(string[] args)
{
var products = new[]
{
new { ProductId = 1, Name = "えんぴつ" },
new { ProductId = 2, Name = "けしごむ" },
new { ProductId = 3, Name = "コンパス" },
new { ProductId = 4, Name = "クレヨン" },
};
var sales = new[]
{
new { SaleId = 1, ProductId = 1, Buyer = "○○商会", Quantity = 2 },
new { SaleId = 2, ProductId = 1, Buyer = "××文具店", Quantity = 4 },
new { SaleId = 3, ProductId = 2, Buyer = "△屋", Quantity = 3 },
new { SaleId = 4, ProductId = 4, Buyer = "○○商会", Quantity = 1 },
new { SaleId = 5, ProductId = 5, Buyer = "○○商会", Quantity = 1 },
};
var nosaled
= new { SaleId = 0, ProductId = 0, Buyer = "(no sales)", Quantity = 0 };
var salesInfo = products.OuterJoin(
sales,
p => p.ProductId,
s => s.ProductId,
(p, s) => new { p.Name, s.Buyer, s.Quantity },
nosaled);
foreach (var i in salesInfo)
{
Console.WriteLine("{0}, {1}, {2}", i.Name, i.Buyer, i.Quantity);
}
}
えんぴつ, ○○商会, 2 えんぴつ, ××文具店, 4 けしごむ, △屋, 3 コンパス, (no sales), 0 クレヨン, ○○商会, 1
var noproduct = new { ProductId = 0, Name = "(no item)" };
var salesInfo = sales.OuterJoin(
products,
s => s.ProductId,
p => p.ProductId,
(s, p) => new { p.Name, s.Buyer, s.Quantity },
noproduct);
えんぴつ, ○○商会, 2 えんぴつ, ××文具店, 4 けしごむ, △屋, 3 クレヨン, ○○商会, 1 (no item), ○○商会, 1
static void Main(string[] args)
{
var rnd = new Random(DateTime.Now.Millisecond);
var items = Enumerable.Range(0, 10000000).Select(_ => new
{
Key1 = rnd.Next(10),
Key2 = rnd.Next(100),
Value = rnd.Next(10000)
});
var sw = new Stopwatch();
sw.Start();
var dic = items.GroupBy(i => new { i.Key1, i.Key2 })
.ToDictionary(g => g.Key, g => g.First().Value);
sw.Stop();
Console.WriteLine("Elapsed:{0}msec", sw.ElapsedMilliseconds);
}
public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(
this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
return new GroupedEnumerable<TSource, TKey, TSource>(
source, keySelector, IdentityFunction<TSource>.Instance, null);
}
internal class GroupedEnumerable<TSource, TKey, TElement>
: IEnumerable<IGrouping<TKey, TElement>>
{
public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator()
{
return Lookup<TKey, TElement>.Create<TSource>(
source, keySelector, elementSelector, comparer).GetEnumerator();
}
}
public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(
this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
return Lookup<TKey, TSource>.Create(
source, keySelector, IdentityFunction<TSource>.Instance, null);
}
What happens when you call ToLookup on an object representing a remote database table with a billion rows in it?なるほど。例えばデータソースがObjectではなくDatabaseだったりしたときに、即時実行しないで済むならそうしたい。LINQのメソッドはデータソースを問わないわけだから、基本的にはGroupByを使い、明示的に即時実行にしたい場合や、実行後のルックアップが必要なら、ToLookupを使うべし。と、解釈して納得できた。
var collection = new [] { "One", "Two", "Three", "Four" };
var dic = collection.ToDictionary(c => c.First());
var collection = new [] { "One", "Two", "Three", "Four" };
var dic = collection.GroupBy(c => c.First())
.ToDictionary(g => g.Key, g => g.First());
public static bool ValidateNotDuplicated(IEnumerable<UserInfo> users)
{
var dupusers = users.GroupBy(u => u.UserId)
.Where(g => g.Count() > 1)
.Select(g => g.Key)
.ToArray();
if (dupusers.Length > 0)
{
Console.WriteLine("User:{0} was duplicated.", string.Join(",", dupusers);
return false;
}
return true;
}
public static IEnumerable<UserInfo> SelectLatest(IEnumerable<UserInfo> users)
{
return users.GroupBy(u => u.UserId)
.Select(g => g.OrderByDescending(u => u.Updated).First());
}
static void ShowGroupedAmounts()
{
var from = new DateTime(2014, 1, 1);
var to = new DateTime(2014, 12, 31);
var group = Sales.Enumerate(from, to)
.GroupBy(s => s.Date.DayOfWeek)
.OrderBy(g => g.Key);
Console.WriteLine("DayOfWeak,Total Amount,Average,Median");
foreach (var g in group)
{
var cnt = g.Count();
Console.WriteLine(
"{0},{1},{2},{3}",
g.Key,
g.Sum(s => s.Amount),
Math.Round(g.Average(s => s.Amount), 1),
g.OrderBy(s => s.Amount).Skip(cnt / 2).First().Amount);
}
}
IEnumerable<IGrouping<DayOfWeak, Sales>>
internal class SelectableKeyedCollection<TKey, TItem>
: KeyedCollection<TKey, TItem>
{
private Func<TItem, TKey> keySelector;
internal SelectableKeyedCollection(Func<TItem, TKey> keySelector)
{
this.keySelector = keySelector;
}
protected override TKey GetKeyForItem(TItem item)
{
return keySelector(item);
}
}
public static class KeyedCollection
{
public static KeyedCollection<TKey, TItem>
Create<TKey, TItem>(Func<TItem, TKey> keySelector)
{
return new SelectableKeyedCollection<TKey, TItem>(keySelector);
}
}
var collection = new SelectableKeyedCollection<X, Y>(x => x.y);
var collection = KeyedCollection.Create((X x) => x.y);
static void Main(string[] args)
{
var week = KeyedCollection.Create((DateTime dt) => dt.DayOfWeek);
foreach (var n in Enumerable.Range(1, 7))
{
week.Add(DateTime.Today.AddDays(n));
}
Console.WriteLine("Today is {0:yyyy/MM/dd (ddd)}", DateTime.Today);
Console.WriteLine();
Console.WriteLine("Next 7 days...");
foreach (var d in week)
{
Console.WriteLine(d.ToShortDateString());
}
Console.WriteLine();
Console.WriteLine(
"Next Friday is {0:yyyy/MM/dd (ddd)}", week[DayOfWeek.Friday]);
}
Today is 2014/10/27 (月) Next 7 days... 2014/10/28 2014/10/29 2014/10/30 2014/10/31 2014/11/01 2014/11/02 2014/11/03 Next Friday is 2014/10/31 (金)
var invalidChars = Path.GetInvalidFileNameChars(); var converted = string.Concat( original.Select(c => invalidChars.Contains(c) ? '_' : c));
var invalidChars = Path.GetInvalidFileNameChars(); var removed = string.Concat(original.Where(c => !invalidChars.Contains(c)));