【VB.NET】LINQ友の会【C#, C♯, C#】
- 1 :デフォルトの名無しさん:2008/02/09(土) 23:51:34
- VisualStudio2008より追加された便利で強力な機能
統合言語クエリ (LINQ : Language Integrated Query)
ちょっと使ってみると、意外と難しいし、テクニック的にも奥が深いものです。
関数型言語にしかないような機能ラムダ式(Lambda式)などはオブジェクト指向とは一味違う機能です。
DataBaseの操作にも、Xmlの操作にも、さらにもっと単純な配列なコンテナにさえ機能する
言語共通・高汎用な統合言語クエリを皆で一緒にマターリ勉強しましょう。
質問、便利なマイテクニックの発表、いろいろやっちゃってください。
- 419 :デフォルトの名無しさん:2009/09/12(土) 23:31:27
- LINQからIEnum処理するところすべてtry-catch(´・ω・`)
- 420 :デフォルトの名無しさん:2009/09/13(日) 00:16:47
- それは、不毛過ぎるw
- 421 :デフォルトの名無しさん:2009/09/14(月) 20:55:08
- 配列の要素を2個ずつ処理したいときにはどうすればいいでしょうか?
ruby の each_slice みたいなのがやりたいのですが。
- 422 :デフォルトの名無しさん:2009/09/14(月) 21:12:59
- static IEnumerable<IEnumerable<TSource>> Slice<TSource>(this IEnumerable<TSource> source, int n)
{
var buf = new TSource[n];
int i = 0;
foreach (var item in source) { buf[i++] = item; if (i == n) { i = 0; yield return buf; } }
if (i != 0) { yield return buf.Take(i); }
}
- 423 :421:2009/09/15(火) 15:00:48
- >>422
ありがとう。
- 424 :デフォルトの名無しさん:2009/09/15(火) 21:59:43
- LINQらしさを追求してみた
source.Select((x, i) => new { Key = i / n, Element = x })
.GroupBy(x => x.Key, x => x.Element)
.Cast<IEnumerable<TSource>>();
- 425 :デフォルトの名無しさん:2009/09/16(水) 06:48:18
- まあどっちでもいいんじゃない?
拡張メソッドはガンガン使うべきなのかは迷うところ。
- 426 :デフォルトの名無しさん:2009/09/16(水) 21:47:09
- イベントをLINQっぽく操れるリアクティブフレームワークってのを最近知ってからというもの
.NET4.0とラブプラスのことで頭が一杯です。
- 427 :422:2009/09/17(木) 11:04:44
- 今更だけど>>422は使われ方によっては問題があるかも
static IEnumerable<IEnumerable<TSource>> Slice<TSource>(this IEnumerable<TSource> source, int n) {
var buf = source.ToArray();
for (int i = 0; i < buf.Length; i += n) yield return buf.Skip(i).Take(n);
}
メモリは食うけどこっちの方が確実
- 428 :デフォルトの名無しさん:2009/09/17(木) 11:22:16
- いやSkipやTake使ったらbufの意味がないな
こんなの用意して代わりに使うか
static IEnumerable<TSource> SkipTake<TSource>(TSource[] source, int skip, int take) {
for (int i = 0; i < take; i++) yield return source[i + skip];
}
- 429 :デフォルトの名無しさん:2009/09/17(木) 17:10:47
- 次はforをForEach()にするんですね
- 430 :デフォルトの名無しさん:2009/09/17(木) 19:00:29
- 427のはあまり良くないと思う。
422のyield return bufを
yield return buf.ToArray()に変えるだけで良いかと。
あと最後はbuf.Take(i)でいいかな。
- 431 :デフォルトの名無しさん:2009/09/17(木) 19:07:12
- sourceがIList<TSource>を実装しているか否かで場合分けするのが効率的か
- 432 :デフォルトの名無しさん:2009/09/27(日) 19:20:03
- 条件に合うものと合わないものを分けるために、
bar = foo.Select(i=>Baz(i) );
foo = foo.Select(i=>!Baz(i));
みたいに2回Selectしてるんですが、
1回で済む方法ないですか?
- 433 :432:2009/09/27(日) 19:23:15
- 間違いました。 where を2回です。
- 434 :デフォルトの名無しさん:2009/09/27(日) 19:24:56
- 欲しいのはどっちなの?
両方ほしいなら2回しないといけないと思うけど。
やりたいことが見えない。
- 435 :デフォルトの名無しさん:2009/09/27(日) 19:37:47
- 両方欲しい場合、自前でループを廻せばワンパスで振り分けできるけど、
Linqで同じようにできないか、っていう質問だろうね。
気持ちは分かるけど多分できないんだろうなあ。
Linqの想定用途はあくまで選択や射影の簡略化だろうし、振り分け処理で
無理矢理Linq使う必要無いんじゃない?と思う。foreachでいいじゃん。
- 436 :デフォルトの名無しさん:2009/09/27(日) 19:49:14
- そういうメソッドを自作すればいい。
IEnumerable<T>受け取ってTuple<IEnumerable<T>, IEnumearble<T>>でもを返すようにしてさ。
- 437 :432:2009/09/27(日) 19:58:37
- 優先度のある条件を集合に適用する処理を
以下のように書きました。
foreach(var 条件 in 条件リスト){
var マッチしたもの = 集合.Where(条件)
集合 = 集合.Where(!条件)
(マッチしたものに対する処理)
}
というループを書いていたのですが、
ruby の partition メソッドみたいなのがあれば
一回ですむじゃん。
と思ったのですが、ヘルプをみてもわからず、
ググってもわからず、なので質問させていただきました。
処理が重いので1パスにしたいというわけではないので、
2回 Where するままにしておきます。
レスありがとうございました。
- 438 :デフォルトの名無しさん:2009/09/27(日) 20:11:24
- やりたいのはこういうこと?
Func<int, bool> cond = x => x % 2 == 0;
var q =
from x in new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, }
let b = cond(x)
group x by b;
var even = q.First(x => x.Key);
var odd = q.First(x => !x.Key);
- 439 :デフォルトの名無しさん:2009/09/27(日) 21:04:04
- だね。
ruby の partition メソッドはズバりGroupBy。
ToLookupはその即時評価版。
- 440 :デフォルトの名無しさん:2009/09/29(火) 02:41:06
- ToLookupなんてあるんだな。
おもしろそうだからこれを使ってFizzBuzzをといてみた。
var nums = Enumerable.Range(1, 100);
var fizzbuzz = nums.ToLookup(num => (num % 15 == 0 ? "fizzBuzz" : (num % 5 == 0 ? "Buzz" : (num % 3 == 0 ? "fizz" : "Other"))), arg => arg);
foreach (var group in fizzbuzz)
{
Console.WriteLine("*****" + group.Key + "*****");
foreach (var num in group)
Console.WriteLine(num.ToString());
}
- 441 :デフォルトの名無しさん:2009/10/10(土) 19:43:10
- プログラミングC#でLINQの項目をちょっと読んでみたが、
C#のコード中に普通にselectとかfromとか書くのは違和感あるなぁ。
C#の予約語になってんのかね?
- 442 :デフォルトの名無しさん:2009/10/10(土) 19:44:40
- >>441
文脈キーワード
- 443 :デフォルトの名無しさん:2009/10/13(火) 12:02:58
- LINQって別に最適プランとか計算しないんでしょ?
ほんのちょっと前までデータベースからデータを「SELECT * FROM TABLE」で持ってきて
コード内でデータの取捨を行うなんて、やっちゃだめの最右翼だったのに、すんげえ
富豪的プログラミングだなあ…。
- 444 :デフォルトの名無しさん:2009/10/13(火) 12:30:06
- WHERE句はあるには有るけど
内部で式評価を最適化しているわけではない
- 445 :デフォルトの名無しさん:2009/10/13(火) 12:54:50
- Linq to Objectにはプランナはない。命令の順番で処理される。
Linq to SQLやEntity Frameworkの場合はDBMSのSQLに翻訳されるから、
DBMSのプランナが機能する。
- 446 :デフォルトの名無しさん:2009/10/13(火) 19:08:08
- LINQ to SQLって、要するに式ツリーからSQLを生成するORMという理解でOK?
- 447 :デフォルトの名無しさん:2009/10/13(火) 19:17:58
- LINQ to SQLの中身がわかってない奴が多いのな。
とりあえずDataContext.Logで吐かれるSQLを確認するところから
はじめたらどうだ?
- 448 :デフォルトの名無しさん:2009/10/13(火) 20:29:13
- ですな。
>>443 のような酷い勘違いは初めて見たけど。
- 449 :デフォルトの名無しさん:2009/10/13(火) 20:40:37
- LINQ to Objectsを最適化するとしたら,DynamicMethodでインライン展開かなあ
コード生成のコストが高いからあんまり意味なさそう
- 450 :デフォルトの名無しさん:2009/10/13(火) 21:37:17
- >>446
Whereの条件とかは式ツリーだけど、Where自体は式ツリーでない
>>447-448
まあ、LINQ to SQLで生成されるSQLも大概だがな
作成したクエリ(IQueryable)をそのまま変換してるからサブクエリが深すぎて何が何やら
- 451 :デフォルトの名無しさん:2009/10/13(火) 23:25:35
- >>446
そう。ただ実行の度に発行される。ToList()すりゃ1回ですむけども。
- 452 :デフォルトの名無しさん:2009/10/26(月) 18:34:12
- /)
///) ノ´⌒`ヽ
/,.=゛''"/γ⌒´ \
/ i f ,.r='"-‐'つ ""´ ⌒\ )
/ / _,.-‐'~ \ / i ) こまけぇことはいいんだよ!!
/ ,i ,二ニ⊃ (・ )` ´( ・) i,/
/ ノ il゛フl (__人_). |
,イ「ト、 ,!,! \ `ー' /
/ iトヾヽ_/ィ" `7 〈
- 453 :デフォルトの名無しさん:2009/11/07(土) 12:28:38
- データは作成する回数よりも参照される回数の方が多いわけで、
キャッシュがないから遅延されても重くなるだけじゃないか?
結局はToList()しまくるハメになっている気がする。
- 454 :デフォルトの名無しさん:2009/11/07(土) 13:04:29
- SQLはちゃらっと書く分には楽だな。
最適化とか考えてくとだんだんめんどくさくなりそうだけど。
つーかいい加減データアクセスモデルはナイスな奴一つにまとめてくれ。
Oslo?
- 455 :デフォルトの名無しさん:2009/11/07(土) 19:58:09
- 確かにMSは昔からデータアクセスの新方式を乱発しすぎなんだよな。
- 456 :デフォルトの名無しさん:2009/11/09(月) 14:02:34
- 遅延評価も即時評価も都合に合わせて選択できるってことで
今のモデルで悪くないと思うがな。
そもそも本当にチューニングが必要な場所ならLinqは使わないだろ。
性能云々うるさいやつ向けに..Optimize()あたりを追加してみるか?
- 457 :デフォルトの名無しさん:2009/11/09(月) 17:37:01
- 手段がいろいろ用意されて軽く破綻してるC++の二の舞ですね
パラダイムを混ぜこぜにするとよく起こる
- 458 :デフォルトの名無しさん:2009/11/10(火) 17:39:44
- 結局のところ記述性と性能はトレードオフなんだよ
- 459 :デフォルトの名無しさん:2009/11/13(金) 00:55:32
- え、いや、Linq の遅延評価は記述性って言うか
スケーラビリティ?だべ。要素数がドカーンって
なっても使えるという意味での。
- 460 :デフォルトの名無しさん:2009/11/15(日) 02:05:16
- SelectMany の戻り値に一つだけ要素を足したいです。
今は、
var list = new List<T>();
list.Add(item);
list.AddRange(foo.SelectMany(i => bar(i)));
のように書いてますが、なんか
冗長な気がします。
1個要素を足すためだけに List のインスタンスを
生成するのは無駄な気がするんですが、
避ける方法ないでしょうか?
- 461 :460:2009/11/15(日) 02:16:19
- すまん、Concat を見つけた。
foo.SelectMany(i=>bar(i)).Concat(new[]{ item });
と書けた。
でも、配列生成してんのが無駄な気がするが、
回避する方法ないよね?
( new List<T>(){ item } とかは無しでw)
- 462 :デフォルトの名無しさん:2009/11/15(日) 03:02:15
- () => { yield return item; }
- 463 :デフォルトの名無しさん:2009/11/15(日) 10:18:15
- ラムダ内をイテレーターブロックにはできないよ。
やるなら、拡張メソッド追加して、
public static IEnumerable<T> Concat(this T x, IEnumerable<T> list)
{
yield return x; foreach(var i in list) yield return i;
}
public static IEnumerable<T> Concat(this IEnumerable<T> list, T x)
{
foreach(var i in list) yield return i; yield return x;
}
- 464 :デフォルトの名無しさん:2009/11/15(日) 11:46:45
- >>461
Enumerable.Repeat(item, 1) で回避。
- 465 :デフォルトの名無しさん:2009/11/15(日) 12:01:40
- 拡張メソッドにT使えたっけ?
- 466 :デフォルトの名無しさん:2009/11/15(日) 12:17:35
- Concat<T>が正解ね
- 467 :デフォルトの名無しさん:2009/11/15(日) 16:28:58
- >>464
それたぶん配列作った方が効率的
Rangeで作られるイテレータよりも配列のイテレータの方がずっと速いはず
- 468 :467:2009/11/15(日) 16:30:40
- 間違えたRepeatか
148 KB
[ 2ちゃんねる 3億PV/日をささえる レンタルサーバー \877/2TB/100Mbps]
取りに行ったけどなかった。次は一時間後に取りに行くです。新着レスの表示
掲示板に戻る
全部
前100
次100
最新50
read.cgi ver 05.0.7.8 2008/11/13 アクチョン仮面 ★
FOX ★ DSO(Dynamic Shared Object)