VisualStudio2008より追加された便利で強力な機能
統合言語クエリ (LINQ : Language Integrated Query)
ちょっと使ってみると、意外と難しいし、テクニック的にも奥が深いものです。
関数型言語にしかないような機能ラムダ式(Lambda式)などはオブジェクト指向とは一味違う機能です。
DataBaseの操作にも、Xmlの操作にも、さらにもっと単純な配列なコンテナにさえ機能する
言語共通・高汎用な統合言語クエリを皆で一緒にマターリ勉強しましょう。
質問、便利なマイテクニックの発表、いろいろやっちゃってください。
探検
【VB.NET】LINQ友の会【C#, C♯, C#】
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2008/02/09(土) 23:51:343635
2008/02/15(金) 10:24:47 さらに集計処理を行います
クエリの中でオブジェクトを生成し、集計処理に利用したりできます
// 拡張子ごとの合計サイズを取得する(foreachを使うとこんな感じ)
Dictionary<string, long> sizeDic = new Dictionary<string, long>();
foreach (var extGroup in extGroupQuery)
{
var sizeQuery1 = from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length;
long totalSize = sizeQuery1.Sum();
sizeDic[extGroup.Key] = totalSize;
}
// 拡張子ごとの合計サイズを取得する(サブクエリを使う)
// クエリ内でさらにクエリを定義できます(totalSizeQueryはsizeQuery1とまったく同じです)
var sizeQuery2 = from extGroup in extGroupQuery
let totalSizeQuery = (from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length)
select new { Extension = extGroup.Key, TotalSize = totalSizeQuery.Sum() };
クエリの中でオブジェクトを生成し、集計処理に利用したりできます
// 拡張子ごとの合計サイズを取得する(foreachを使うとこんな感じ)
Dictionary<string, long> sizeDic = new Dictionary<string, long>();
foreach (var extGroup in extGroupQuery)
{
var sizeQuery1 = from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length;
long totalSize = sizeQuery1.Sum();
sizeDic[extGroup.Key] = totalSize;
}
// 拡張子ごとの合計サイズを取得する(サブクエリを使う)
// クエリ内でさらにクエリを定義できます(totalSizeQueryはsizeQuery1とまったく同じです)
var sizeQuery2 = from extGroup in extGroupQuery
let totalSizeQuery = (from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length)
select new { Extension = extGroup.Key, TotalSize = totalSizeQuery.Sum() };
3735
2008/02/15(金) 10:26:11 // .Sum()の場所を変えてみる(結果はsizeQuery2と同じです)
var sizeQuery3 = from extGroup in extGroupQuery
let totalSize = (from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length).Sum()
select new { Extension = extGroup.Key, TotalSize = totalSize };
// サブクエリを拡張メソッドに変えてみる(場合によってはサブクエリよりもすっきり書けます)
var sizeQuery4 = from extGroup in extGroupQuery
let totalSize = extGroup.Select<string, long>(filename => new System.IO.FileInfo(filename).Length).Sum()
select new { Extension = extGroup.Key, TotalSize = totalSize };
// extGroupQuery, sizeQuery2をまとめてみる
var sizeQuery5 = from filename in files
let ext = System.IO.Path.GetExtension(filename).ToLower()
group filename by ext into extGroup
let totalSizeQuery = (from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length)
select new { Extension = extGroup.Key, TotalSize = totalSizeQuery };
とりあえず以上です。
もっと気の利いた例を作ったら、また書き込みます。
var sizeQuery3 = from extGroup in extGroupQuery
let totalSize = (from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length).Sum()
select new { Extension = extGroup.Key, TotalSize = totalSize };
// サブクエリを拡張メソッドに変えてみる(場合によってはサブクエリよりもすっきり書けます)
var sizeQuery4 = from extGroup in extGroupQuery
let totalSize = extGroup.Select<string, long>(filename => new System.IO.FileInfo(filename).Length).Sum()
select new { Extension = extGroup.Key, TotalSize = totalSize };
// extGroupQuery, sizeQuery2をまとめてみる
var sizeQuery5 = from filename in files
let ext = System.IO.Path.GetExtension(filename).ToLower()
group filename by ext into extGroup
let totalSizeQuery = (from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length)
select new { Extension = extGroup.Key, TotalSize = totalSizeQuery };
とりあえず以上です。
もっと気の利いた例を作ったら、また書き込みます。
3835
2008/02/15(金) 11:52:15 >>35-37の応用で、ファイルの重複を検出するコードをLINQでコンパクトに書いてみます。
次のメソッドが存在するという前提です。
static string GetMD5String(string filename)
{
using (System.Security.Cryptography.MD5CryptoServiceProvider md5
= new System.Security.Cryptography.MD5CryptoServiceProvider())
{
byte[] data = System.IO.File.ReadAllBytes(filename);
byte[] hash = md5.ComputeHash(data);
StringBuilder buf = new StringBuilder();
foreach (byte b in hash)
{
buf.AppendFormat("{0:x2}", b);
}
return buf.ToString();
}
}
次のメソッドが存在するという前提です。
static string GetMD5String(string filename)
{
using (System.Security.Cryptography.MD5CryptoServiceProvider md5
= new System.Security.Cryptography.MD5CryptoServiceProvider())
{
byte[] data = System.IO.File.ReadAllBytes(filename);
byte[] hash = md5.ComputeHash(data);
StringBuilder buf = new StringBuilder();
foreach (byte b in hash)
{
buf.AppendFormat("{0:x2}", b);
}
return buf.ToString();
}
}
3935
2008/02/15(金) 11:52:51 まずは単純だけど遅いバージョンから
// ファイルをハッシュ値でグループ化する
// 全ファイルを読み込んでハッシュ値を計算するので遅いです
var hashGroupQuery = from filehash in
(from filename in files
let hash = GetMD5String(filename)
select new { Filename = filename, Hash = hash })
group filehash by filehash.Hash into hashGroup
where hashGroup.Count() >= 2
select hashGroup;
foreach (var hashGroup in hashGroupQuery)
{
Console.WriteLine("Hash: {0}, Count: {1}", hashGroup.Key, hashGroup.Count());
foreach (var filehash in hashGroup)
{
Console.WriteLine("\t{0}", filehash.Filename);
}
}
// ファイルをハッシュ値でグループ化する
// 全ファイルを読み込んでハッシュ値を計算するので遅いです
var hashGroupQuery = from filehash in
(from filename in files
let hash = GetMD5String(filename)
select new { Filename = filename, Hash = hash })
group filehash by filehash.Hash into hashGroup
where hashGroup.Count() >= 2
select hashGroup;
foreach (var hashGroup in hashGroupQuery)
{
Console.WriteLine("Hash: {0}, Count: {1}", hashGroup.Key, hashGroup.Count());
foreach (var filehash in hashGroup)
{
Console.WriteLine("\t{0}", filehash.Filename);
}
}
4035
2008/02/15(金) 11:56:08 次に前処理を行って高速化したバージョン
// 処理を高速化するため、ファイルサイズでグループ化しておく
// (ファイルサイズはファイルを読み込まなくても取得できるので)
var sizeGroupQuery = from filesize in
(from filename in files
let fileinfo = new System.IO.FileInfo(filename)
let size = fileinfo.Length
select new { Filename = filename, Size = size })
group filesize by filesize.Size into sizeGroup
where sizeGroup.Count() >= 2
select sizeGroup;
foreach (var sizeGroup in sizeGroupQuery)
{
// ハッシュ値でグループ化する
var hashGroupQuery2 = from filehash in
(from filesize in sizeGroup
let hash = GetMD5String(filesize.Filename)
select new { Filename = filesize.Filename, Hash = hash })
group filehash by filehash.Hash into hashGroup
where hashGroup.Count() >= 2
select hashGroup;
foreach (var hashGroup in hashGroupQuery2)
{
// (行数オーバーのため略 >>39と同じです)
}
}
// 処理を高速化するため、ファイルサイズでグループ化しておく
// (ファイルサイズはファイルを読み込まなくても取得できるので)
var sizeGroupQuery = from filesize in
(from filename in files
let fileinfo = new System.IO.FileInfo(filename)
let size = fileinfo.Length
select new { Filename = filename, Size = size })
group filesize by filesize.Size into sizeGroup
where sizeGroup.Count() >= 2
select sizeGroup;
foreach (var sizeGroup in sizeGroupQuery)
{
// ハッシュ値でグループ化する
var hashGroupQuery2 = from filehash in
(from filesize in sizeGroup
let hash = GetMD5String(filesize.Filename)
select new { Filename = filesize.Filename, Hash = hash })
group filehash by filehash.Hash into hashGroup
where hashGroup.Count() >= 2
select hashGroup;
foreach (var hashGroup in hashGroupQuery2)
{
// (行数オーバーのため略 >>39と同じです)
}
}
41デフォルトの名無しさん
2008/02/16(土) 00:03:522008/02/16(土) 00:04:35
Q.データを確認したい
ツールバーにある DataGridView は、とりあえずデータの中身を見てみたい時にとても便利です。
DataSource プロパティーにデータをセットする事で見ることができます。
ただし、ここに設定できるオブジェクトは IList , IListSource , IBindingList , IBindingListView
の四つです。
また、要素は、フィールドメンバでは駄目で、プロパティーでなければなりません。
C# 3.0 より追加された省略形が便利です。
class Row {
public int Data1 { set ; get ; }
public int Data2 { set ; get ; }
}
dataGridView1.DataSource = new Row[] { new Row() { Data1 = 1, Data2 = 2 } };
ツールバーにある DataGridView は、とりあえずデータの中身を見てみたい時にとても便利です。
DataSource プロパティーにデータをセットする事で見ることができます。
ただし、ここに設定できるオブジェクトは IList , IListSource , IBindingList , IBindingListView
の四つです。
また、要素は、フィールドメンバでは駄目で、プロパティーでなければなりません。
C# 3.0 より追加された省略形が便利です。
class Row {
public int Data1 { set ; get ; }
public int Data2 { set ; get ; }
}
dataGridView1.DataSource = new Row[] { new Row() { Data1 = 1, Data2 = 2 } };
2008/02/16(土) 00:05:16
Q.from ... として作ったデータが見れない
IList 等に変換してしまうのが便利です。
var tableX = new [] {
new { X=1 , P=0.25 },
new { X=2 , P=0.50 },
new { X=3 , P=0.25 },
};
var table2 = from row in tableX orderby row.P select row;
dataGridView1.DataSource = table2.ToArray();
IList 等に変換してしまうのが便利です。
var tableX = new [] {
new { X=1 , P=0.25 },
new { X=2 , P=0.50 },
new { X=3 , P=0.25 },
};
var table2 = from row in tableX orderby row.P select row;
dataGridView1.DataSource = table2.ToArray();
2008/02/16(土) 00:05:53
Q.表の中から必要な要素を選択したい
where句を使います。
class Row {
public int X { set ; get ; }
public double P { set ; get ; }
}
var tableX = new Row[] {
new Row() { X=1 , P=0.25 },
new Row() { X=2 , P=0.50 },
new Row() { X=3 , P=0.25 },
};
// Xが2以下の行を選択する
var table1 = from row in tableX where row.X <= 2 select row;
// Xが2以下の行を選択したのち、さらに P <= 0.25 となる行を絞り込む
var table2 = from row in tableX where row.X <= 2 where row.P <= 0.25 select row;
dataGridView1.DataSource = table1.ToArray();
dataGridView2.DataSource = table2.ToArray();
where句を使います。
class Row {
public int X { set ; get ; }
public double P { set ; get ; }
}
var tableX = new Row[] {
new Row() { X=1 , P=0.25 },
new Row() { X=2 , P=0.50 },
new Row() { X=3 , P=0.25 },
};
// Xが2以下の行を選択する
var table1 = from row in tableX where row.X <= 2 select row;
// Xが2以下の行を選択したのち、さらに P <= 0.25 となる行を絞り込む
var table2 = from row in tableX where row.X <= 2 where row.P <= 0.25 select row;
dataGridView1.DataSource = table1.ToArray();
dataGridView2.DataSource = table2.ToArray();
2008/02/16(土) 00:06:24
Q.表をソートしたい
1.orderby句を使います、単純なソートは以下の通りです。
class Row {
public string S { set; get; }
public int D { set; get; }
}
var tableOrg = new Row[] {
new Row() { D=3 },
new Row() { D=1 },
new Row() { D=4 },
new Row() { D=1 },
new Row() { D=5 },
new Row() { D=9 },
};
// 昇順(ascending省略可)
var table1 = from row in tableOrg orderby row.D ascending select row;
// 降順
var table2 = from row in tableOrg orderby row.D descending select row;
dataGridView1.DataSource = table1.ToArray();
dataGridView2.DataSource = table2.ToArray();
1.orderby句を使います、単純なソートは以下の通りです。
class Row {
public string S { set; get; }
public int D { set; get; }
}
var tableOrg = new Row[] {
new Row() { D=3 },
new Row() { D=1 },
new Row() { D=4 },
new Row() { D=1 },
new Row() { D=5 },
new Row() { D=9 },
};
// 昇順(ascending省略可)
var table1 = from row in tableOrg orderby row.D ascending select row;
// 降順
var table2 = from row in tableOrg orderby row.D descending select row;
dataGridView1.DataSource = table1.ToArray();
dataGridView2.DataSource = table2.ToArray();
2008/02/16(土) 00:15:04
2.二つ以上の項目についてソートする場合は以下の通りです。
class Row {
public string S { set; get; }
public int D { set; get; }
}
var tableOrg = new Row[] {
new Row() { S="A" , D=3 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=4 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=5 },
new Row() { S="B" , D=9 },
};
// SとD を使って比較します
var table1 = from row in tableOrg orderby row.S, row.D select row;
dataGridView1.DataSource = table1.ToArray();
class Row {
public string S { set; get; }
public int D { set; get; }
}
var tableOrg = new Row[] {
new Row() { S="A" , D=3 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=4 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=5 },
new Row() { S="B" , D=9 },
};
// SとD を使って比較します
var table1 = from row in tableOrg orderby row.S, row.D select row;
dataGridView1.DataSource = table1.ToArray();
2008/02/16(土) 00:15:29
3.二回に分けてソートする場合は以下の通りです。(2と結果が異なります)
class Row {
public string S { set; get; }
public int D { set; get; }
}
var tableOrg = new Row[] {
new Row() { S="A" , D=3 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=4 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=5 },
new Row() { S="B" , D=9 },
};
// SとD を使って比較します
var table1 = from row in tableOrg orderby row.S orderby row.D select row;
dataGridView1.DataSource = table1.ToArray();
class Row {
public string S { set; get; }
public int D { set; get; }
}
var tableOrg = new Row[] {
new Row() { S="A" , D=3 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=4 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=5 },
new Row() { S="B" , D=9 },
};
// SとD を使って比較します
var table1 = from row in tableOrg orderby row.S orderby row.D select row;
dataGridView1.DataSource = table1.ToArray();
2008/02/16(土) 09:02:20
ところで、LINQってどう発音するの?
2008/02/16(土) 09:48:38
発音は link と同じらしいよ。
2008/02/16(土) 17:51:35
>>1 です、今日は、表の結合のやり方を紹介します。
2008/02/16(土) 17:52:36
Q.表を結合したい1(クロス結合)
Row1の表にRow2の表の要素をすべて結合します。
class Row1 { public string S { set; get; } }
class Row2 { public string S { set; get; } }
class Row3 { public string R1 { set; get; } public string R2 { set; get; } }
var tableOrg1 = new Row1[] { new Row1() { S="赤" }, new Row1() { S="青" },};
var tableOrg2 = new Row2[] { new Row2() { S="青" }, new Row2() { S="緑" },};
var table1 = from row1 in tableOrg1 from row2 in tableOrg2 select new Row3() { R1 = row1.S, R2 = row2.S };
dataGridView1.DataSource = table1.ToArray();
dataGridView2.DataSource = table2.ToArray();
table1 の結果
赤 青
赤 緑
青 青
青 緑
この機能、一見は使い道がなさそうですが、これをフィルターしてゆく事により価値が出てきます。
Row1の表にRow2の表の要素をすべて結合します。
class Row1 { public string S { set; get; } }
class Row2 { public string S { set; get; } }
class Row3 { public string R1 { set; get; } public string R2 { set; get; } }
var tableOrg1 = new Row1[] { new Row1() { S="赤" }, new Row1() { S="青" },};
var tableOrg2 = new Row2[] { new Row2() { S="青" }, new Row2() { S="緑" },};
var table1 = from row1 in tableOrg1 from row2 in tableOrg2 select new Row3() { R1 = row1.S, R2 = row2.S };
dataGridView1.DataSource = table1.ToArray();
dataGridView2.DataSource = table2.ToArray();
table1 の結果
赤 青
赤 緑
青 青
青 緑
この機能、一見は使い道がなさそうですが、これをフィルターしてゆく事により価値が出てきます。
2008/02/16(土) 17:53:19
Q.表を結合したい2(等価結合、きっと良く使うに違いない)
Row1の表にRow2の表の要素を普通に結合します。
この例では、 tableOrg1 の Index 番号と同じ Index のある tableOrg2 の列に結合します。
class Row1 { public int LineNo { set; get; } public int Index { set; get; } }
class Row2 { public int Index { set; get; } public string Data1 { set; get; } public string Data2 { set; get; } }
class Row3 { public int LineNo { set; get; } public string Data1 { set; get; } public string Data2 { set; get; } }
var tableOrg1 = new Row1[] {
new Row1() { LineNo=1 , Index = 3 },
new Row1() { LineNo=2 , Index = 1 },
new Row1() { LineNo=3 , Index = 4 },
new Row1() { LineNo=4 , Index = 1 },
new Row1() { LineNo=5 , Index = 5 },
};
var tableOrg2 = new Row2[] {
new Row2() { Index=1 , Data1 = "Index1" , Data2="ABC" },
new Row2() { Index=2 , Data1 = "Index2" , Data2="DEF" },
new Row2() { Index=3 , Data1 = "Index3" , Data2="GHI" },
new Row2() { Index=4 , Data1 = "Index4" , Data2="JKL" },
new Row2() { Index=5 , Data1 = "Index5" , Data2="MNL" },
};
var table1 = from row1 in tableOrg1 join row2 in tableOrg2 on row1.Index equals row2.Index select new Row3() { LineNo = row1.LineNo, Data1 = row2.Data1, Data2 = row2.Data2 };
table1 の結果
1 Index3 GHI
2 Index1 ABC
3 Index4 JKL
4 Index1 ABC
5 Index5 MNL
Row1の表にRow2の表の要素を普通に結合します。
この例では、 tableOrg1 の Index 番号と同じ Index のある tableOrg2 の列に結合します。
class Row1 { public int LineNo { set; get; } public int Index { set; get; } }
class Row2 { public int Index { set; get; } public string Data1 { set; get; } public string Data2 { set; get; } }
class Row3 { public int LineNo { set; get; } public string Data1 { set; get; } public string Data2 { set; get; } }
var tableOrg1 = new Row1[] {
new Row1() { LineNo=1 , Index = 3 },
new Row1() { LineNo=2 , Index = 1 },
new Row1() { LineNo=3 , Index = 4 },
new Row1() { LineNo=4 , Index = 1 },
new Row1() { LineNo=5 , Index = 5 },
};
var tableOrg2 = new Row2[] {
new Row2() { Index=1 , Data1 = "Index1" , Data2="ABC" },
new Row2() { Index=2 , Data1 = "Index2" , Data2="DEF" },
new Row2() { Index=3 , Data1 = "Index3" , Data2="GHI" },
new Row2() { Index=4 , Data1 = "Index4" , Data2="JKL" },
new Row2() { Index=5 , Data1 = "Index5" , Data2="MNL" },
};
var table1 = from row1 in tableOrg1 join row2 in tableOrg2 on row1.Index equals row2.Index select new Row3() { LineNo = row1.LineNo, Data1 = row2.Data1, Data2 = row2.Data2 };
table1 の結果
1 Index3 GHI
2 Index1 ABC
3 Index4 JKL
4 Index1 ABC
5 Index5 MNL
2008/02/16(土) 17:54:00
Q.表を結合したい3(非等価結合、やや使う違いない)
let を使って、選択した行を保持する事により実現できます。
class 得点表 { public string 氏名 { set; get; } public int 得点 { set; get; } }
class 評価表 { public int 以上 { set; get; } public int 未満 { set; get; } public string 評価 { set; get; } }
class 氏名と評価 { public string 氏名 { set; get; } public string 評価 { set; get; } }
var tableOrg1 = new 得点表[] {
new 得点表() { 氏名="Aさん" , 得点=10 },
new 得点表() { 氏名="Bさん" , 得点=100 },
new 得点表() { 氏名="Cさん" , 得点=60 },
};
var tableOrg2 = new 評価表[] {
new 評価表() { 以上=0 , 未満=20, 評価="丙" },
new 評価表() { 以上=20 , 未満=70, 評価="乙" },
new 評価表() { 以上=70 , 未満=101, 評価="甲" },
};
var table1 = from row1 in tableOrg1
let selectLines = from row2 in tableOrg2 where (row2.以上 <= row1.得点 && row1.得点 < row2.未満) select row2
select new 氏名と評価() { 氏名 = row1.氏名, 評価 = selectLines.First().評価 };
table1 の結果
Aさん 丙
Bさん 甲
Cさん 乙
あんま綺麗じゃない……equalsに対してLINQの拡張求む > Microsoft
let を使って、選択した行を保持する事により実現できます。
class 得点表 { public string 氏名 { set; get; } public int 得点 { set; get; } }
class 評価表 { public int 以上 { set; get; } public int 未満 { set; get; } public string 評価 { set; get; } }
class 氏名と評価 { public string 氏名 { set; get; } public string 評価 { set; get; } }
var tableOrg1 = new 得点表[] {
new 得点表() { 氏名="Aさん" , 得点=10 },
new 得点表() { 氏名="Bさん" , 得点=100 },
new 得点表() { 氏名="Cさん" , 得点=60 },
};
var tableOrg2 = new 評価表[] {
new 評価表() { 以上=0 , 未満=20, 評価="丙" },
new 評価表() { 以上=20 , 未満=70, 評価="乙" },
new 評価表() { 以上=70 , 未満=101, 評価="甲" },
};
var table1 = from row1 in tableOrg1
let selectLines = from row2 in tableOrg2 where (row2.以上 <= row1.得点 && row1.得点 < row2.未満) select row2
select new 氏名と評価() { 氏名 = row1.氏名, 評価 = selectLines.First().評価 };
table1 の結果
Aさん 丙
Bさん 甲
Cさん 乙
あんま綺麗じゃない……equalsに対してLINQの拡張求む > Microsoft
54デフォルトの名無しさん
2008/02/16(土) 17:54:50 そのうち、逆引きLINQでも作って、纏めてみたいな……
こうやって、Q&A を作ってみると、LINQは集合の積的な演算は強いのに和の方は至って貧弱なんですね。
全部LINQにしなくても適当にメソッドを使えば良いという話もありますが……
こうやって、Q&A を作ってみると、LINQは集合の積的な演算は強いのに和の方は至って貧弱なんですね。
全部LINQにしなくても適当にメソッドを使えば良いという話もありますが……
2008/02/16(土) 18:39:49
>>54
まあ、リレーショナルデータベースがそういうものだからね<テーブル積を多用
まあ、リレーショナルデータベースがそういうものだからね<テーブル積を多用
2008/02/16(土) 18:59:05
2008/02/16(土) 19:11:27
そういう概念を導入すると、
作り手だけでなくて、使い手にも圏論の知識を強要することにならないかな。
LINQ は、リレーショナルデータベースの文化を
OOP 言語に導入したものだから、
少なくとも SQL チックに select とか where ってキーワードを使ってる限り、
リレーショナルデータベースの文化を大きく逸脱するようなことは
しない方がいいと思う。
ヘジたんがクエリ式否定派(関数形式ばっかり使う)な理由も
そういうところにあるのかもね。
作り手だけでなくて、使い手にも圏論の知識を強要することにならないかな。
LINQ は、リレーショナルデータベースの文化を
OOP 言語に導入したものだから、
少なくとも SQL チックに select とか where ってキーワードを使ってる限り、
リレーショナルデータベースの文化を大きく逸脱するようなことは
しない方がいいと思う。
ヘジたんがクエリ式否定派(関数形式ばっかり使う)な理由も
そういうところにあるのかもね。
2008/02/16(土) 19:11:51
>>53
ちょっとだけ短くしたよ。
var table1 = from row1 in tableOrg1
let 評価 = tableOrg2.First(row2 => row2.以上 <= row1.得点 && row1.得点 < row2.未満)
select new { row1.氏名, 評価.評価 };
ちょっとだけ短くしたよ。
var table1 = from row1 in tableOrg1
let 評価 = tableOrg2.First(row2 => row2.以上 <= row1.得点 && row1.得点 < row2.未満)
select new { row1.氏名, 評価.評価 };
2008/02/16(土) 19:15:04
あと、同値分類みたいなのは、group by じゃだめ?
6058
2008/02/16(土) 19:24:17 >>53
パターンマッチっぽくしてみたよ。
var table1 =
from row1 in tableOrg1
let 評価結果 = tableOrg2.Where(row2 => row2.以上 <= row1.得点 && row1.得点 < row2.未満)
.Select(row2 => row2.評価)
.Concat(Enumerable.Repeat("見つからないよ", 1))
.Take(1)
from 評価 in 評価結果
select new { row1.氏名, 評価 };
パターンマッチっぽくしてみたよ。
var table1 =
from row1 in tableOrg1
let 評価結果 = tableOrg2.Where(row2 => row2.以上 <= row1.得点 && row1.得点 < row2.未満)
.Select(row2 => row2.評価)
.Concat(Enumerable.Repeat("見つからないよ", 1))
.Take(1)
from 評価 in 評価結果
select new { row1.氏名, 評価 };
2008/02/16(土) 20:13:38
>>1です
>>57
概念を導入することと、どう表現してどう使わせるかは違うと思うんですよ
高度な概念も、図にしてみれば、あんたバカ、何当り前の事をと思わずにはいられない概念は多いと思うんですよ。
圏論のそんな物の内の一つだと思っています。
ちなみにヘジたん理論無視の直感実装大好きです、実装は理屈じゃないですよ、いいと思ったらそれがいいんだと思ってます。
理屈は後付け、原爆の爆縮レンズが開発される時に、火薬職人が二種類の火薬使えばいいじゃんといって、頭でっかちのノイマンが計算するっていうのは悪くないと
ここでは、火薬職人がヘジたんで、頭でっかちがリサーチの人たちですね。
>>60
ありがとさんです、なるほどなるほど、いろいろ参考になりますです。
まだまだ初心者なんで今後ともよろしくお願いします。
>>57
概念を導入することと、どう表現してどう使わせるかは違うと思うんですよ
高度な概念も、図にしてみれば、あんたバカ、何当り前の事をと思わずにはいられない概念は多いと思うんですよ。
圏論のそんな物の内の一つだと思っています。
ちなみにヘジたん理論無視の直感実装大好きです、実装は理屈じゃないですよ、いいと思ったらそれがいいんだと思ってます。
理屈は後付け、原爆の爆縮レンズが開発される時に、火薬職人が二種類の火薬使えばいいじゃんといって、頭でっかちのノイマンが計算するっていうのは悪くないと
ここでは、火薬職人がヘジたんで、頭でっかちがリサーチの人たちですね。
>>60
ありがとさんです、なるほどなるほど、いろいろ参考になりますです。
まだまだ初心者なんで今後ともよろしくお願いします。
2008/02/16(土) 20:26:54
高度な概念といえば、たとえばλ式なんかがそうなんですが、関数だと思うと恐ろしい事になりますが、
あれってとどのつまりは、引数が添え字になっている唯のベクトルですよね。なにやら要素が並んでいるだけの物です。
よく無限次元になってしまうので、普通に書けないからああ書いたというだけで……
もっと解り易くならないかなと思ったりします。
あれってとどのつまりは、引数が添え字になっている唯のベクトルですよね。なにやら要素が並んでいるだけの物です。
よく無限次元になってしまうので、普通に書けないからああ書いたというだけで……
もっと解り易くならないかなと思ったりします。
2008/02/16(土) 21:07:54
DB屋もやってる俺からみると、これはぶっちゃけキモい
変にSQLの知識あるとちょっと慣れそうにないなぁ、これは
変にSQLの知識あるとちょっと慣れそうにないなぁ、これは
2008/02/17(日) 00:29:39
>>63
俺も一応オラクルマスター持ちなんだが(システム屋から足を洗って長いけど)、
それはそれ、これはこれだな。
DBとだけ使っている限りは、SQL以上のことができるわけじゃないから「ただのキモいSQL」という見方も、そう間違ってはいないだろう。
SQLを基準にして見れば、SQLとの違いが気持ち悪いのは確か。しかし、メモリ上のデータのグループ化やら結合やら、定型的なわりに再利用しづらいコードを
いちいち書いては「こんな処理、SQLならSELECT文一発なのに」と思っていた人にとっては、むしろSQLに近づいた感じなのではないだろうか。
俺も一応オラクルマスター持ちなんだが(システム屋から足を洗って長いけど)、
それはそれ、これはこれだな。
DBとだけ使っている限りは、SQL以上のことができるわけじゃないから「ただのキモいSQL」という見方も、そう間違ってはいないだろう。
SQLを基準にして見れば、SQLとの違いが気持ち悪いのは確か。しかし、メモリ上のデータのグループ化やら結合やら、定型的なわりに再利用しづらいコードを
いちいち書いては「こんな処理、SQLならSELECT文一発なのに」と思っていた人にとっては、むしろSQLに近づいた感じなのではないだろうか。
2008/02/17(日) 00:53:13
OOP 言語が SQL に近づいたこと
(より「意図通りに書ける」ようになった)も重要だし、
in-memory オブジェクト、XML、DB に対して
ほぼ同じ書式でクエリが書けることも重要かと。
(より「意図通りに書ける」ようになった)も重要だし、
in-memory オブジェクト、XML、DB に対して
ほぼ同じ書式でクエリが書けることも重要かと。
2008/02/17(日) 20:41:50
LINQとSQLの違いのひとつにプランナの有無がある。
LINQは処理順に書かなくてはならないし、必ず記述順で処理される。
LINQはSQLの類似品と考えるより、
Enumeratorやコールバック(ラムダ)を使ったパイプライン処理であり
コレクション処理の延長だと思ったほうが誤解がない。
LINQは処理順に書かなくてはならないし、必ず記述順で処理される。
LINQはSQLの類似品と考えるより、
Enumeratorやコールバック(ラムダ)を使ったパイプライン処理であり
コレクション処理の延長だと思ったほうが誤解がない。
2008/02/17(日) 21:31:55
2008/02/17(日) 21:32:46
Q.表を分割したい
LINQの文法は、例えば以下のような形式になっています。
from アイテム名 in 元データ where アイテム名.項目=="条件のあっているデータ" select 新しい行の定義
上記の文の最後の部分「select 新しい行の定義」の部分を「group 新しい行の定義 by ふるい分けの基準となる値」
とする事により表を分割できます。
ここでは
1 "ABC"
2 "DEF"
3 "ABC"
4 "DEF"
5 "GHI"
となっている表を、以下の三つの表に分割する方法です。
ABC のある列
1 ABC
3 ABC
DEF のある列
2 DEF
4 DEF
GHI のある列
5 GHI
LINQの文法は、例えば以下のような形式になっています。
from アイテム名 in 元データ where アイテム名.項目=="条件のあっているデータ" select 新しい行の定義
上記の文の最後の部分「select 新しい行の定義」の部分を「group 新しい行の定義 by ふるい分けの基準となる値」
とする事により表を分割できます。
ここでは
1 "ABC"
2 "DEF"
3 "ABC"
4 "DEF"
5 "GHI"
となっている表を、以下の三つの表に分割する方法です。
ABC のある列
1 ABC
3 ABC
DEF のある列
2 DEF
4 DEF
GHI のある列
5 GHI
2008/02/17(日) 21:33:19
ツールボックスから DataGridView と TextBox を三つ貼り付けて以下のコードを実行すると三つの表が完成します。
var tableOrg1 = new[] {
new { LineNo = 1 , Data = "ABC" } ,
new { LineNo = 2 , Data = "DEF" } ,
new { LineNo = 3 , Data = "ABC" } ,
new { LineNo = 4 , Data = "DEF" } ,
new { LineNo = 5 , Data = "GHI" } ,
};
var dataGridViewArray = new[] { dataGridView1, dataGridView2, dataGridView3 };
var textBoxArray = new[] { textBox1, textBox2, textBox3 };
var tableArray = (from row in tableOrg1 group row by row.Data).ToArray();
for (int i = 0; i < dataGridViewArray.GetLength(0) && i < tableArray.GetLength(0); ++i) {
dataGridViewArray[i].DataSource = tableArray[i].ToArray();
textBoxArray[i].Text = tableArray[i].Key.ToString();
}
by row.Data の部分を変更することにより、例えばby row.Data.Length などとする事により複雑なふるい分けが可能です。
var tableOrg1 = new[] {
new { LineNo = 1 , Data = "ABC" } ,
new { LineNo = 2 , Data = "DEF" } ,
new { LineNo = 3 , Data = "ABC" } ,
new { LineNo = 4 , Data = "DEF" } ,
new { LineNo = 5 , Data = "GHI" } ,
};
var dataGridViewArray = new[] { dataGridView1, dataGridView2, dataGridView3 };
var textBoxArray = new[] { textBox1, textBox2, textBox3 };
var tableArray = (from row in tableOrg1 group row by row.Data).ToArray();
for (int i = 0; i < dataGridViewArray.GetLength(0) && i < tableArray.GetLength(0); ++i) {
dataGridViewArray[i].DataSource = tableArray[i].ToArray();
textBoxArray[i].Text = tableArray[i].Key.ToString();
}
by row.Data の部分を変更することにより、例えばby row.Data.Length などとする事により複雑なふるい分けが可能です。
2008/02/17(日) 21:34:14
Q.特定項目で分類したい
項目に大小比較ができれば、ソートしてしまえば良いのですが、それが無い場合には少し困った事になります。
ここでは、前出の「表を分割したい」と組み合わせた方法を紹介します。
それは、前出のLINQ文「from row in tableOrg1 group row by row.Data」の後ろに「into tmp1 from tmp2 in tmp1 select tmp2」を追加して
from row in tableOrg1 group row by row.Data into tmp1 from tmp2 in tmp1 select tmp2
とすると実現できます、まじないの部類ですが・・・うまく行きます。
var tableOrg1 = new[] {
new { LineNo = 1 , Data = "ABC" } ,
new { LineNo = 2 , Data = "DEF" } ,
new { LineNo = 3 , Data = "ABC" } ,
new { LineNo = 4 , Data = "DEF" } ,
new { LineNo = 5 , Data = "GHI" } ,
};
var table1 = from row in tableOrg1 group row by row.Data into tmp1 from tmp2 in tmp1 select tmp2;
dataGridView1.DataSource = table1.ToArray();
項目に大小比較ができれば、ソートしてしまえば良いのですが、それが無い場合には少し困った事になります。
ここでは、前出の「表を分割したい」と組み合わせた方法を紹介します。
それは、前出のLINQ文「from row in tableOrg1 group row by row.Data」の後ろに「into tmp1 from tmp2 in tmp1 select tmp2」を追加して
from row in tableOrg1 group row by row.Data into tmp1 from tmp2 in tmp1 select tmp2
とすると実現できます、まじないの部類ですが・・・うまく行きます。
var tableOrg1 = new[] {
new { LineNo = 1 , Data = "ABC" } ,
new { LineNo = 2 , Data = "DEF" } ,
new { LineNo = 3 , Data = "ABC" } ,
new { LineNo = 4 , Data = "DEF" } ,
new { LineNo = 5 , Data = "GHI" } ,
};
var table1 = from row in tableOrg1 group row by row.Data into tmp1 from tmp2 in tmp1 select tmp2;
dataGridView1.DataSource = table1.ToArray();
71デフォルトの名無しさん
2008/02/17(日) 21:35:03 linq の文法 query-body ::= query-body-clause* final-query-clause query-continuation?
この query-body-clause* の部分が複数になると急に難解になりますね。
どういう時に、使うと見通しが良くなるのか、あるいはどういう時にろくな事にならないのか
パターンとアンチパターンを揃える必要がある気がします。
この query-body-clause* の部分が複数になると急に難解になりますね。
どういう時に、使うと見通しが良くなるのか、あるいはどういう時にろくな事にならないのか
パターンとアンチパターンを揃える必要がある気がします。
2008/02/17(日) 21:40:18
2008/02/18(月) 18:11:36
>>1 です、今日は、LINQ文法の詳細をやろうと思ったのですが……
一通りざらっと見てみて、LINQの文法はひょっとして質が悪いのでは?という疑惑が湧いてきました。
LINQの核心部分は、from join その他 LINQ キーワードではなく、実際の処理が記述されている System.Linq.Enumerable であるので
これが致命傷になるとは思えないのですが、簡単に使うための上っ面としては今一な気がします。
このキーワードと文法には、変な汎用性があり、相当な広範囲にわたって複雑な処理が可能ですが
それを行うなら、メソッドベースで行ったほうが良さそうな気がします。
1.方向性としては、良くある定型について、LINQ 文法を使って完結に記述。使用例一覧に纏めておき、サクッと使う。
2.例外的なクエリについては、メソッドを使い、一つ一つ区切りながらクエリを完成させる。
こういう使い方が良いのではと思い始めました。
皆さんはどんな意見をお持ちでしょうか?
一通りざらっと見てみて、LINQの文法はひょっとして質が悪いのでは?という疑惑が湧いてきました。
LINQの核心部分は、from join その他 LINQ キーワードではなく、実際の処理が記述されている System.Linq.Enumerable であるので
これが致命傷になるとは思えないのですが、簡単に使うための上っ面としては今一な気がします。
このキーワードと文法には、変な汎用性があり、相当な広範囲にわたって複雑な処理が可能ですが
それを行うなら、メソッドベースで行ったほうが良さそうな気がします。
1.方向性としては、良くある定型について、LINQ 文法を使って完結に記述。使用例一覧に纏めておき、サクッと使う。
2.例外的なクエリについては、メソッドを使い、一つ一つ区切りながらクエリを完成させる。
こういう使い方が良いのではと思い始めました。
皆さんはどんな意見をお持ちでしょうか?
74デフォルトの名無しさん
2008/02/18(月) 18:13:51 http://www.microsoft.com/japan/msdn/net/bb308959.aspx より。
今日はこれを、初心者向けの説明にしようと思ったのですが……難しすぎ
区切り無く、際限なく、限りなく書き方が広がるとマニュアル化ができません。
query-continuation? の定義に query-body があるのが最悪だ。
だれがこれを手際よく解説するアイディアお持ちで無いでしょうか?
query-body ::= query-body-clause* final-query-clause query-continuation?
query-body-clause ::= (from-clause | join-clause | let-clause | where-clause | orderby-clause)
join-clause ::= join itemName in srcExpr on keyExpr equals keyExpr (into itemName)?
let-clause ::= let itemName = selExpr
where-clause ::= where predExpr
orderby-clause ::= orderby (keyExpr (ascending | descending)?)*
final-query-clause ::= (select-clause | groupby-clause)
select-clause ::= select selExpr
groupby-clause ::= group selExpr by keyExpr
query-continuation ::= into itemName query-body
#ひょっとしてカンマ忘れてる?
#orderby-clause ::= orderby (keyExpr (ascending | descending)? ,)*
今日はこれを、初心者向けの説明にしようと思ったのですが……難しすぎ
区切り無く、際限なく、限りなく書き方が広がるとマニュアル化ができません。
query-continuation? の定義に query-body があるのが最悪だ。
だれがこれを手際よく解説するアイディアお持ちで無いでしょうか?
query-body ::= query-body-clause* final-query-clause query-continuation?
query-body-clause ::= (from-clause | join-clause | let-clause | where-clause | orderby-clause)
join-clause ::= join itemName in srcExpr on keyExpr equals keyExpr (into itemName)?
let-clause ::= let itemName = selExpr
where-clause ::= where predExpr
orderby-clause ::= orderby (keyExpr (ascending | descending)?)*
final-query-clause ::= (select-clause | groupby-clause)
select-clause ::= select selExpr
groupby-clause ::= group selExpr by keyExpr
query-continuation ::= into itemName query-body
#ひょっとしてカンマ忘れてる?
#orderby-clause ::= orderby (keyExpr (ascending | descending)? ,)*
2008/02/18(月) 18:52:44
>>73
LINQ って言葉の指す範囲は広くて、クエリ式もメソッド形式もどっちも LINQ よ。
from x in list みたいなのはクエリ式。
クエリ式でないと書きづらいのは、多重 from と join と let くらいかな。
まあ、transparent な変数が絡むとクエリ式使わないときつい。
逆に、クエリ式で書けないことも実に多い。
まあ、個人的には、
クエリ式で書けるものは全部クエリ式で、
それ以外だけメソッド形式で書いてる。
LINQ って言葉の指す範囲は広くて、クエリ式もメソッド形式もどっちも LINQ よ。
from x in list みたいなのはクエリ式。
クエリ式でないと書きづらいのは、多重 from と join と let くらいかな。
まあ、transparent な変数が絡むとクエリ式使わないときつい。
逆に、クエリ式で書けないことも実に多い。
まあ、個人的には、
クエリ式で書けるものは全部クエリ式で、
それ以外だけメソッド形式で書いてる。
2008/02/18(月) 18:56:38
2008/02/18(月) 19:00:39
対応関係としては、
from x in list where x > 0 select x;
↓
list.Where(x => x > 0); // 最後の Select はきえる
from x in list select x * x;
↓
list.Select(x => x * x);
from x in list select x * x into y where y > 5 select y;
↓
list.Select(x => x * x).Where(y => y > 5); // .Select の後ろにさらにメソッドが続く
from x in list where x > 0 select x;
↓
list.Where(x => x > 0); // 最後の Select はきえる
from x in list select x * x;
↓
list.Select(x => x * x);
from x in list select x * x into y where y > 5 select y;
↓
list.Select(x => x * x).Where(y => y > 5); // .Select の後ろにさらにメソッドが続く
2008/02/20(水) 00:08:01
2008/02/20(水) 04:36:32
Hibernate とは違うの?
2008/02/20(水) 10:09:28
2008/02/20(水) 18:48:34
2008/02/20(水) 20:25:54
>>79
簡単に言うと、O/Rマッピングは対症療法、LINQは原因療法、みたいな。
なんでこんなのが必要かってのは、
ttp://d.hatena.ne.jp/fromdusktildawn/20060216/1140064918
を読むと理解が深まるかも。
簡単に言うと、O/Rマッピングは対症療法、LINQは原因療法、みたいな。
なんでこんなのが必要かってのは、
ttp://d.hatena.ne.jp/fromdusktildawn/20060216/1140064918
を読むと理解が深まるかも。
2008/02/20(水) 21:16:01
LINQ最大の効果ポイントは、一般化と高速化にあるんじゃないかな
データベースから、XMLから、果ては適当なクラスや構造体まで統一手法で操作可能という点。
O/Rマッピングと目指すところがそもそも違うと思う
データベースから、XMLから、果ては適当なクラスや構造体まで統一手法で操作可能という点。
O/Rマッピングと目指すところがそもそも違うと思う
2008/02/20(水) 22:14:52
キャッシュポリシーは単純だけど、Linq to SQLはORM。
これだけはほかのと系統が違う。これで使うラムダ式は特殊なもの。
これだけはほかのと系統が違う。これで使うラムダ式は特殊なもの。
2008/02/20(水) 23:37:59
( ゚д゚)ノ ハイ!シツモーン!です。
次のように追加してくと実行時間がリニアに増えてくんだけど何か間違えてるんでしょうか?
プロジェクトごとあげてみました。
http://www.borujoa.org/upload/source/upload16875.zip
class Program {
static void Main(string[] args) {
var db =new TestDB(@"testDB.sdf");
db.DeleteDatabase();
db.CreateDatabase();
var count=0;
var tu=new TickUtil();
tu.WriteLine("begin--");
while(count++<5000){
var person=new Person{Name=string.Format("name-{0:8d}",count),
Age=count,Explanation=string.Format("Explain-{0}",count)};
db.Persons.InsertOnSubmit(person);
db.SubmitChanges();
if(count%100==0)
tu.WriteLine("new person-count={0}",count);
}
tu.WriteLine("end-");
}
}
次のように追加してくと実行時間がリニアに増えてくんだけど何か間違えてるんでしょうか?
プロジェクトごとあげてみました。
http://www.borujoa.org/upload/source/upload16875.zip
class Program {
static void Main(string[] args) {
var db =new TestDB(@"testDB.sdf");
db.DeleteDatabase();
db.CreateDatabase();
var count=0;
var tu=new TickUtil();
tu.WriteLine("begin--");
while(count++<5000){
var person=new Person{Name=string.Format("name-{0:8d}",count),
Age=count,Explanation=string.Format("Explain-{0}",count)};
db.Persons.InsertOnSubmit(person);
db.SubmitChanges();
if(count%100==0)
tu.WriteLine("new person-count={0}",count);
}
tu.WriteLine("end-");
}
}
2008/02/21(木) 01:06:41
LINQでWin32のメッセージマップって書けないの?
2008/02/21(木) 01:43:02
C++/CLI には無いの?
2008/02/21(木) 07:12:47
>>85
遅くなるというのは1件あたりの処理時間が増えるということかな?
それだったらCompact Editonなのが影響してるのかもしれない。
2005Expressで実行してみたらどうだろう。
db.SubmitChanges(); は5000件まとめての方が速いと思う。
メモリがきついようなら500件くらいまとめてで。
遅くなるというのは1件あたりの処理時間が増えるということかな?
それだったらCompact Editonなのが影響してるのかもしれない。
2005Expressで実行してみたらどうだろう。
db.SubmitChanges(); は5000件まとめての方が速いと思う。
メモリがきついようなら500件くらいまとめてで。
2008/02/21(木) 08:46:06
2008/02/21(木) 10:05:01
>>85のソースから
> protected string SetAndReturnDifferenceTimeString() {
> int current = Environment.TickCount;
> int lastDiff = current - _last;
> _last = current;
> return "[" + lastDiff + "]";
> }
> public void WriteLine(string message) {
> Console.WriteLine(message + " " + SetAndReturnDifferenceTimeString());
> }
> public void WriteLine(string message, params object[] args) {
> WriteLine(string.Format(message, args));
> }
100件毎に実行されるのってWriteLine(string message, params object[] args)じゃね?
最近プログラミングしてないんで間違ってたらスマソ
> protected string SetAndReturnDifferenceTimeString() {
> int current = Environment.TickCount;
> int lastDiff = current - _last;
> _last = current;
> return "[" + lastDiff + "]";
> }
> public void WriteLine(string message) {
> Console.WriteLine(message + " " + SetAndReturnDifferenceTimeString());
> }
> public void WriteLine(string message, params object[] args) {
> WriteLine(string.Format(message, args));
> }
100件毎に実行されるのってWriteLine(string message, params object[] args)じゃね?
最近プログラミングしてないんで間違ってたらスマソ
2008/02/21(木) 10:13:41
>>90
下のWriteLine()の中で上のを呼んでる。
下のWriteLine()の中で上のを呼んでる。
2008/02/22(金) 00:11:14
>>1 です
クエリ式はとりあえず放って置いて、メソッドでしか表現できないタイプのものを解説してみようと思っているのですが
まずは一発目で Aggregate あたりからやってみようかと思ってます。
ただ、このメソッドあまりにも関数型言語らしい仕様をしています。
何か良い説明方法はないかと色々さがしているのですが、良いのがあったら誰か紹介してください。
http://d.hatena.ne.jp/blanketsky/20071129/1196329379
とりあえず、この辺りとか見てみたのですが……
こんなの見せられたら初心者さん気絶するよなとか思いつつ、何かいいのはないかなと……
クエリ式はとりあえず放って置いて、メソッドでしか表現できないタイプのものを解説してみようと思っているのですが
まずは一発目で Aggregate あたりからやってみようかと思ってます。
ただ、このメソッドあまりにも関数型言語らしい仕様をしています。
何か良い説明方法はないかと色々さがしているのですが、良いのがあったら誰か紹介してください。
http://d.hatena.ne.jp/blanketsky/20071129/1196329379
とりあえず、この辺りとか見てみたのですが……
こんなの見せられたら初心者さん気絶するよなとか思いつつ、何かいいのはないかなと……
2008/02/22(金) 00:32:05
>>92
forループからの置き換えで解釈してみては。
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
これをAggregateで記述するとどうなるか、とか。
forループからの置き換えで解釈してみては。
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
これをAggregateで記述するとどうなるか、とか。
9485
2008/02/22(金) 00:39:59 Comapctでまとめて実行するようにしたらリニアに増加するのはなくなった様。
10000件ぐらいまではまとめたほうがトータルの実行時間が短くなった。
もっと多くした場合はどうなるかは今度試します。
ほかのデータベース試してないけれど、なんかCompactのせいっぽい匂いが・・・
10000件ぐらいまではまとめたほうがトータルの実行時間が短くなった。
もっと多くした場合はどうなるかは今度試します。
ほかのデータベース試してないけれど、なんかCompactのせいっぽい匂いが・・・
2008/02/22(金) 01:20:37
>>92
その情熱がどこから来るのかわからんが、Aggregateなら
・sum、factあたりを通常の再帰関数で書く
・共通する部分を抜き出す
・これがAggregateです
っていうのがわかりやすいんじゃないの?
その情熱がどこから来るのかわからんが、Aggregateなら
・sum、factあたりを通常の再帰関数で書く
・共通する部分を抜き出す
・これがAggregateです
っていうのがわかりやすいんじゃないの?
2008/02/22(金) 11:23:52
2008/02/22(金) 19:46:15
クエリ式はきもいけどLINQ自体はないと生きていけんよ
コレクションに対するアルゴリズムは絶対に必要だ
XMLやSQLは別になくても生きていけるとは思うが
コレクションに対するアルゴリズムは絶対に必要だ
XMLやSQLは別になくても生きていけるとは思うが
98デフォルトの名無しさん
2008/02/22(金) 22:13:522008/02/23(土) 01:08:33
>>1 です
>>93 結局ループをどの様に書くかという問題なのだからそれが一番いいような気がしました。
それと、これは群論の本(数学の本です)を読んでいて、抽象化は具体例を限りなく沢山作ってその中から共通の物を取り出すことだという記述があって
それも考慮にいれて、まず具体例、それからループへと展開する方針でいってみようと思います。
>>95
申し訳ないですが、再帰は最終手段だと思います、非常に良くないと思います。それ以外の部分は賛成です。
再帰とラムダ(or Delegate)は絶対に最初に記述して説明してはならないものだと確信しています。
>>96
>http://ufcpp.net/study/csharp/introduction.html
>実を言うと、僕は趣味でプログラミングをしてるだけで、 C# は研究とは一切関係なかったりします。
>(むしろ C/C++ を使うことが多かった。 2007年追記: 最近では割となんでも C# で書くようになりました。)
>初めて C# について調べてみたとき(ちょうど Java に物足りなさを感じ、SUNの方針に憤りを感じていたころです)、
> C# が普及してくれればプログラミングにかかる手間は大幅に削減されると感じるました。
>しかし、Microsoft は順調に行かなさそうなものはばっさりと切り捨てることで有名な企業ですし、
>世間の C# への関心が低ければ、C# は普及することなく消え去ってしまうでしょう。
>そこで、少しでも早く C# が普及するようにとの願いを込めて当コンテンツを作成することにしました。
実は自分も全く同じ境遇です、でも研究者じゃありません、ただのプログラマですが……
関数型言語をやっていて思うところで、こんなの一発なのにというコードがオブジェクト指向のスタイルでは全くまともにかけなくて歯がゆい思いをしていました。
今日からお休みなので、これから練ってみます、明後日辺りから書き始めるかもしれません。
>>93 結局ループをどの様に書くかという問題なのだからそれが一番いいような気がしました。
それと、これは群論の本(数学の本です)を読んでいて、抽象化は具体例を限りなく沢山作ってその中から共通の物を取り出すことだという記述があって
それも考慮にいれて、まず具体例、それからループへと展開する方針でいってみようと思います。
>>95
申し訳ないですが、再帰は最終手段だと思います、非常に良くないと思います。それ以外の部分は賛成です。
再帰とラムダ(or Delegate)は絶対に最初に記述して説明してはならないものだと確信しています。
>>96
>http://ufcpp.net/study/csharp/introduction.html
>実を言うと、僕は趣味でプログラミングをしてるだけで、 C# は研究とは一切関係なかったりします。
>(むしろ C/C++ を使うことが多かった。 2007年追記: 最近では割となんでも C# で書くようになりました。)
>初めて C# について調べてみたとき(ちょうど Java に物足りなさを感じ、SUNの方針に憤りを感じていたころです)、
> C# が普及してくれればプログラミングにかかる手間は大幅に削減されると感じるました。
>しかし、Microsoft は順調に行かなさそうなものはばっさりと切り捨てることで有名な企業ですし、
>世間の C# への関心が低ければ、C# は普及することなく消え去ってしまうでしょう。
>そこで、少しでも早く C# が普及するようにとの願いを込めて当コンテンツを作成することにしました。
実は自分も全く同じ境遇です、でも研究者じゃありません、ただのプログラマですが……
関数型言語をやっていて思うところで、こんなの一発なのにというコードがオブジェクト指向のスタイルでは全くまともにかけなくて歯がゆい思いをしていました。
今日からお休みなので、これから練ってみます、明後日辺りから書き始めるかもしれません。
100デフォルトの名無しさん
2008/02/23(土) 01:09:33 しかし、http://msdn2.microsoft.com/ja-jp/library/bb549218.aspx
これをみて理解できる人間が一体何人いるんだろうか……
Aggregate<(Of <(TSource, TAccumulate>)>)(IEnumerable<(Of <(TSource>)>), TAccumulate, Func<(Of <(TAccumulate, TSource, TAccumulate>)>))
この表現からぱっと見た目に使い方がわかる人は一体何人いるんだろうと、首を傾げそうになります。
ドキュメントのつくりを一度見直すべきだと思う……強力なのに……
>世間の C# への関心が低ければ、C# は普及することなく消え去ってしまうでしょう。
こんな状態になって欲しくないです
これを使えば、エクセルで小計等をやるような操作を一行で書き下せますが、使える人が居なくなってしまう。
これをみて理解できる人間が一体何人いるんだろうか……
Aggregate<(Of <(TSource, TAccumulate>)>)(IEnumerable<(Of <(TSource>)>), TAccumulate, Func<(Of <(TAccumulate, TSource, TAccumulate>)>))
この表現からぱっと見た目に使い方がわかる人は一体何人いるんだろうと、首を傾げそうになります。
ドキュメントのつくりを一度見直すべきだと思う……強力なのに……
>世間の C# への関心が低ければ、C# は普及することなく消え去ってしまうでしょう。
こんな状態になって欲しくないです
これを使えば、エクセルで小計等をやるような操作を一行で書き下せますが、使える人が居なくなってしまう。
101デフォルトの名無しさん
2008/02/23(土) 01:22:13 C++にBoostその他の取り合わせなんか、正にそんな世間の関心が低い状態。
LINQもそういうことになってしまうのは嫌だな。
LINQもそういうことになってしまうのは嫌だな。
102デフォルトの名無しさん
2008/02/23(土) 02:31:52 一応世間に知られてからもう大分経つでしょ・・・
これ流行らないよ・・・
from の位置とか外人さんでも気持ちわるいんじゃないかな
これ流行らないよ・・・
from の位置とか外人さんでも気持ちわるいんじゃないかな
10395
2008/02/23(土) 02:36:28 >>99
あー、ごめん、関数型言語とごっちゃになってた。
C#なら95の最初の手順を
・sum、factあたりを通常の関数で書く
でいいな。確かに再帰とかいらない。
蛇足ですが、あなたの対象とする「初心者」像がいまいちわからないのが
少し気になります。
あー、ごめん、関数型言語とごっちゃになってた。
C#なら95の最初の手順を
・sum、factあたりを通常の関数で書く
でいいな。確かに再帰とかいらない。
蛇足ですが、あなたの対象とする「初心者」像がいまいちわからないのが
少し気になります。
104デフォルトの名無しさん
2008/02/23(土) 03:22:34105デフォルトの名無しさん
2008/02/23(土) 10:15:51 Selectが X->Y のマップになってるのはちょっと名前がわかり辛くて見つけられなかったな
duck typing(?)とかいう手法で Map :: X[] -> (X -> Y) -> Y[] を作っちゃった
拡張性も結構あるしガクジュツ的ではなくちゃんと実務に沿って開発しやすくなるような言語拡張だからLINQは流行ると思う
duck typing(?)とかいう手法で Map :: X[] -> (X -> Y) -> Y[] を作っちゃった
拡張性も結構あるしガクジュツ的ではなくちゃんと実務に沿って開発しやすくなるような言語拡張だからLINQは流行ると思う
106デフォルトの名無しさん
2008/02/23(土) 13:41:16 Enumerable.ForEachがほしい
107デフォルトの名無しさん
2008/02/23(土) 14:51:39 要望出してSP1に入れさせようぜ
108デフォルトの名無しさん
2008/02/23(土) 14:52:38 >>106 自分で作りなはれ。自分は作った。
109デフォルトの名無しさん
2008/02/23(土) 14:56:38 晒して
110デフォルトの名無しさん
2008/02/23(土) 15:10:50 void ForEach<T>(this IEnumerable<T> source, Action<T> action) {
foreach(T item in source) action(item);
}
ただこれだけのことだけど
こんなことしちゃうとコード全体がガラッと変わるから非公式にやるのは抵抗がある
foreach(T item in source) action(item);
}
ただこれだけのことだけど
こんなことしちゃうとコード全体がガラッと変わるから非公式にやるのは抵抗がある
111デフォルトの名無しさん
2008/02/23(土) 15:17:25 なんでもかんでも一行でやろうとするのはC#的じゃないだろ
foreachぐらい分けて書こうぜ
foreachぐらい分けて書こうぜ
112デフォルトの名無しさん
2008/02/23(土) 15:42:04113デフォルトの名無しさん
2008/02/23(土) 16:44:36 foreachのみで簡潔に書けるものはforeachのみで良いと思います
foreach( var row in table ) 文 ;
これ以上何かをする必要はないだろうと思う、逆にややこしいだけだし。
はなしは変わって、http://ufcpp.net/study/csharp/sp3_stdqueryo.html#aggregate によると
> でも、メソッド提供だけでは、 join や let などがどうしてもきれいに表現できなかったので、
<やむなく SQL 風のクエリ式を導入したそうです。
>(プログラミング言語の中に別に言語を埋め込むというのはデメリットも大きくて、
>言語制作者にとっては結構ためらわれる行為。)
>(join や let をきれいに書くためには、どうしても透過識別子のような考え方が必要だった。)
という事らしいのですが、私は、むしろ逆で、これを見た瞬間λ式消滅、これは素晴らしい!!
と思ったものなんですが……
"Language Integrated" Query というぐらいですから、最初こちらがあったのだと想像していのですが逆だったんですね。
foreach にはλ式は登場しないので十分だと思っています。
foreach( var row in table ) 文 ;
これ以上何かをする必要はないだろうと思う、逆にややこしいだけだし。
はなしは変わって、http://ufcpp.net/study/csharp/sp3_stdqueryo.html#aggregate によると
> でも、メソッド提供だけでは、 join や let などがどうしてもきれいに表現できなかったので、
<やむなく SQL 風のクエリ式を導入したそうです。
>(プログラミング言語の中に別に言語を埋め込むというのはデメリットも大きくて、
>言語制作者にとっては結構ためらわれる行為。)
>(join や let をきれいに書くためには、どうしても透過識別子のような考え方が必要だった。)
という事らしいのですが、私は、むしろ逆で、これを見た瞬間λ式消滅、これは素晴らしい!!
と思ったものなんですが……
"Language Integrated" Query というぐらいですから、最初こちらがあったのだと想像していのですが逆だったんですね。
foreach にはλ式は登場しないので十分だと思っています。
114デフォルトの名無しさん
2008/02/23(土) 16:47:27 デザイナを使っているとdelegateやeventなんて全然意識しやいじゃないですか
ダブルクリックすれば勝手にコード登場となって、こういうややこしいものは後回しにして使い方を最初に知ることができる。
これがC#の良い点だと思うんですよ。
ダブルクリックすれば勝手にコード登場となって、こういうややこしいものは後回しにして使い方を最初に知ることができる。
これがC#の良い点だと思うんですよ。
115デフォルトの名無しさん
2008/02/23(土) 16:50:49 List<T>やArrayにはForEachがあるだろ
匿名メソッドよりも,普通のメソッドを直接渡すときに気持ちいいんだよね
list.ForEach(Console.WriteLine);みたいに
初めてみたときはびっくりしたけど
匿名メソッドよりも,普通のメソッドを直接渡すときに気持ちいいんだよね
list.ForEach(Console.WriteLine);みたいに
初めてみたときはびっくりしたけど
116デフォルトの名無しさん
2008/02/23(土) 16:59:23 普通にプログラミングしててもSelectやWhereは腐る程出てきて
それらを書くぶんにはクエリ式でなく拡張メソッド+ラムダ式の方がシンプルに書ける
ラムダ式は他にもプログラミングのあらゆる局面で使うと便利なことが多い
対してクエリ式はSelectManyやJoinなんかで使うとシンプルに書けるけど
そんなん滅多に使わん
それらを書くぶんにはクエリ式でなく拡張メソッド+ラムダ式の方がシンプルに書ける
ラムダ式は他にもプログラミングのあらゆる局面で使うと便利なことが多い
対してクエリ式はSelectManyやJoinなんかで使うとシンプルに書けるけど
そんなん滅多に使わん
117デフォルトの名無しさん
2008/02/23(土) 17:43:25 遅延評価のせいで,一旦必要な部分を評価しないといけないのか・・・
new[] { 1, 2, 3, 4, 5 }.Select(
x => {
Console.WriteLine(x);
return x;
}
).ToArray();
new[] { 1, 2, 3, 4, 5 }.Select(
x => {
Console.WriteLine(x);
return x;
}
).ToArray();
118デフォルトの名無しさん
2008/02/23(土) 18:06:36 遅延評価の問題すっかり忘れてた、あんまり意識する必要無いとおもったけど、デバッグ時にも面倒が起りますね。
あなたがその値を見るまでは値は計算されていませんって、まるでシュレディンガーの猫のような現象がありました。
あなたがその値を見るまでは値は計算されていませんって、まるでシュレディンガーの猫のような現象がありました。
119デフォルトの名無しさん
2008/02/23(土) 18:24:47 普通に書いたらええがな
120デフォルトの名無しさん
2008/02/23(土) 18:29:18 .ToList().ForEach(Console.WriteLine) でいいじゃん
121デフォルトの名無しさん
2008/02/23(土) 18:30:33 ToList超きもい
122デフォルトの名無しさん
2008/02/23(土) 18:32:42 遅延評価はLINQだと実態があいまいになりがちだがHaskellを使うと、なんというかテツガクしたくなる。
ものすごく面白いが、万人にお勧めではない。
ものすごく面白いが、万人にお勧めではない。
123デフォルトの名無しさん
2008/02/23(土) 18:35:44 IEnumerable<>でforeachするときの例っぽいの書こうとした^p^
124デフォルトの名無しさん
2008/02/27(水) 19:00:07 >>1 です
ちょっとスタイル変更、くだすれC#だと、配列よりも List クラスの方が需要ありそうだったので。
実際、実用上は配列って事はありえない気がしますし。
名前は全部漢字にして、型名には末尾に"型" と付けてみました。
ちょっとスタイル変更、くだすれC#だと、配列よりも List クラスの方が需要ありそうだったので。
実際、実用上は配列って事はありえない気がしますし。
名前は全部漢字にして、型名には末尾に"型" と付けてみました。
125デフォルトの名無しさん
2008/02/27(水) 19:00:49 Q.売上表で小計をもとめるような計算をしたい(1)
Aggregate が便利です。
以下の例では、合計原価と合計売価を求めます。解りやすさ優先で、型をすべて書ききったバージョンです。
System.Collections.Generic.List<売上帳の行型> 売上帳 = new System.Collections.Generic.List<売上帳の行型>();
売上帳.Add(new 売上帳の行型() { 品名 = "デスクトップPC", 数量 = 1, 原価 = 100000, 売価 = 120000 });
売上帳.Add(new 売上帳の行型() { 品名 = "ノートPC", 数量 = 2, 原価 = 250000, 売価 = 280000 });
// お試し表示
dataGridView1.DataSource = 売上帳;
// 合計の計算方法
合計型 合計の初期値 = new 合計型() { 合計原価 = 0, 合計売価 = 0 };
合計型 合計表 = 売上帳.Aggregate(
合計の初期値,
(合計型 直前の合計, 売上帳の行型 行) => new 合計型() { 合計原価 = 直前の合計.合計原価 + 行.数量 * 行.原価, 合計売価 = 直前の合計.合計売価 + 行.数量 * 行.売価 }
);
dataGridView2.DataSource = new 合計型[] { 合計表 };
public class 売上帳の行型 {
public string 品名 { get; set; }
public int 数量 { get; set; }
public int 原価 { get; set; }
public int 売価 { get; set; }
}
public struct 合計型 {
public int 合計原価 { get; set; }
public int 合計売価 { get; set; }
}
Aggregate が便利です。
以下の例では、合計原価と合計売価を求めます。解りやすさ優先で、型をすべて書ききったバージョンです。
System.Collections.Generic.List<売上帳の行型> 売上帳 = new System.Collections.Generic.List<売上帳の行型>();
売上帳.Add(new 売上帳の行型() { 品名 = "デスクトップPC", 数量 = 1, 原価 = 100000, 売価 = 120000 });
売上帳.Add(new 売上帳の行型() { 品名 = "ノートPC", 数量 = 2, 原価 = 250000, 売価 = 280000 });
// お試し表示
dataGridView1.DataSource = 売上帳;
// 合計の計算方法
合計型 合計の初期値 = new 合計型() { 合計原価 = 0, 合計売価 = 0 };
合計型 合計表 = 売上帳.Aggregate(
合計の初期値,
(合計型 直前の合計, 売上帳の行型 行) => new 合計型() { 合計原価 = 直前の合計.合計原価 + 行.数量 * 行.原価, 合計売価 = 直前の合計.合計売価 + 行.数量 * 行.売価 }
);
dataGridView2.DataSource = new 合計型[] { 合計表 };
public class 売上帳の行型 {
public string 品名 { get; set; }
public int 数量 { get; set; }
public int 原価 { get; set; }
public int 売価 { get; set; }
}
public struct 合計型 {
public int 合計原価 { get; set; }
public int 合計売価 { get; set; }
}
126デフォルトの名無しさん
2008/02/27(水) 19:01:50 >>125の続き 売上表で小計をもとめるような計算をしたい(2)
省けそうな型名は省略したバージョンです
var 売上帳 = new System.Collections.Generic.List<売上帳の行型>();
売上帳.Add(new 売上帳の行型() { 品名 = "デスクトップPC", 数量 = 1, 原価 = 100000, 売価 = 120000 });
売上帳.Add(new 売上帳の行型() { 品名 = "ノートPC", 数量 = 2, 原価 = 250000, 売価 = 280000 });
// お試し表示
dataGridView1.DataSource = 売上帳;
// 合計の計算方法
var 合計表 = 売上帳.Aggregate(
new { 合計原価 = 0, 合計売価 = 0 },
(直前の合計, 行) => new { 合計原価 = 直前の合計.合計原価 + 行.数量 * 行.原価, 合計売価 = 直前の合計.合計売価 + 行.数量 * 行.売価 }
);
dataGridView2.DataSource = new[] { 合計表 };
省けそうな型名は省略したバージョンです
var 売上帳 = new System.Collections.Generic.List<売上帳の行型>();
売上帳.Add(new 売上帳の行型() { 品名 = "デスクトップPC", 数量 = 1, 原価 = 100000, 売価 = 120000 });
売上帳.Add(new 売上帳の行型() { 品名 = "ノートPC", 数量 = 2, 原価 = 250000, 売価 = 280000 });
// お試し表示
dataGridView1.DataSource = 売上帳;
// 合計の計算方法
var 合計表 = 売上帳.Aggregate(
new { 合計原価 = 0, 合計売価 = 0 },
(直前の合計, 行) => new { 合計原価 = 直前の合計.合計原価 + 行.数量 * 行.原価, 合計売価 = 直前の合計.合計売価 + 行.数量 * 行.売価 }
);
dataGridView2.DataSource = new[] { 合計表 };
127デフォルトの名無しさん
2008/02/27(水) 19:03:01 >>126の続き 売上表で小計をもとめるような計算をしたい(3)
上記のコードが何をしているのかといいますと、以下のコードのような処理をしています。
var 売上帳 = new System.Collections.Generic.List<売上帳の行型>();
売上帳.Add(new 売上帳の行型() { 品名 = "デスクトップPC", 数量 = 1, 原価 = 100000, 売価 = 120000 });
売上帳.Add(new 売上帳の行型() { 品名 = "ノートPC", 数量 = 2, 原価 = 250000, 売価 = 280000 });
// お試し表示
dataGridView1.DataSource = 売上帳;
// 合計の計算方法
var 直前の合計 = new { 合計原価 = 0, 合計売価 = 0 };
foreach (売上帳の行型 行 in 売上帳)
{
直前の合計 = new { 合計原価 = 直前の合計.合計原価 + 行.数量 * 行.原価, 合計売価 = 直前の合計.合計売価 + 行.数量 * 行.売価 };
}
dataGridView2.DataSource = new[] { 直前の合計 };
上記のコードが何をしているのかといいますと、以下のコードのような処理をしています。
var 売上帳 = new System.Collections.Generic.List<売上帳の行型>();
売上帳.Add(new 売上帳の行型() { 品名 = "デスクトップPC", 数量 = 1, 原価 = 100000, 売価 = 120000 });
売上帳.Add(new 売上帳の行型() { 品名 = "ノートPC", 数量 = 2, 原価 = 250000, 売価 = 280000 });
// お試し表示
dataGridView1.DataSource = 売上帳;
// 合計の計算方法
var 直前の合計 = new { 合計原価 = 0, 合計売価 = 0 };
foreach (売上帳の行型 行 in 売上帳)
{
直前の合計 = new { 合計原価 = 直前の合計.合計原価 + 行.数量 * 行.原価, 合計売価 = 直前の合計.合計売価 + 行.数量 * 行.売価 };
}
dataGridView2.DataSource = new[] { 直前の合計 };
128デフォルトの名無しさん
2008/02/27(水) 19:04:24 >>127の続き 売上表で小計をもとめるような計算をしたい(4)
これを使うと簡単になるケース
合計型と売上帳の行型が同じなら、コードは単純になります
var 売上帳 = new System.Collections.Generic.List<売上帳の行型>();
売上帳.Add(new 売上帳の行型() { 品名 = "デスクトップPC", 数量 = 1, 原価 = 100000, 売価 = 120000 });
売上帳.Add(new 売上帳の行型() { 品名 = "ノートPC", 数量 = 2, 原価 = 250000, 売価 = 280000 });
// 合計の計算
var 合計行 = 売上帳.Aggregate((直前の合計, 現在の行) => new 売上帳の行型() { 原価 = 直前の合計.原価 + 現在の行.数量 * 現在の行.原価, 売価 = 直前の合計.売価 + 現在の行.数量 * 現在の行.売価, 品名 = "合計" });
売上帳.Add(合計行);
// お試し表示
dataGridView1.DataSource = 売上帳;
これを使うと簡単になるケース
合計型と売上帳の行型が同じなら、コードは単純になります
var 売上帳 = new System.Collections.Generic.List<売上帳の行型>();
売上帳.Add(new 売上帳の行型() { 品名 = "デスクトップPC", 数量 = 1, 原価 = 100000, 売価 = 120000 });
売上帳.Add(new 売上帳の行型() { 品名 = "ノートPC", 数量 = 2, 原価 = 250000, 売価 = 280000 });
// 合計の計算
var 合計行 = 売上帳.Aggregate((直前の合計, 現在の行) => new 売上帳の行型() { 原価 = 直前の合計.原価 + 現在の行.数量 * 現在の行.原価, 売価 = 直前の合計.売価 + 現在の行.数量 * 現在の行.売価, 品名 = "合計" });
売上帳.Add(合計行);
// お試し表示
dataGridView1.DataSource = 売上帳;
129デフォルトの名無しさん
2008/02/27(水) 19:05:23 まとめ
駄目だ、どうあがいても単純になりません。
3 番目を書いてみたら、foreach で書いたほうが見通しがよさそうな感じすらしてきます。
綺麗になるのは、アキュムレーターの型とコンテナ要素の型が一致しているとき
もしくはアキュムレーターの型が int のような単純型で有る場合に限られます。
メソッド方式にはやはり何かが足りない感じがします。
LINQの新規キーワードとして、それも foreach をイメージできるような構文にして
"aggregate 売上帳" と書いたら、型名、その他をインテリセンスがズバズバッと書き出して、
作る側は中身をを書くだけといった具合になれば使えそうな気がするのですが……
もしくは Excel の、式のコピーのようなイメージができれば、やる事は一番上の式を書く事となるのですが。
駄目だ、どうあがいても単純になりません。
3 番目を書いてみたら、foreach で書いたほうが見通しがよさそうな感じすらしてきます。
綺麗になるのは、アキュムレーターの型とコンテナ要素の型が一致しているとき
もしくはアキュムレーターの型が int のような単純型で有る場合に限られます。
メソッド方式にはやはり何かが足りない感じがします。
LINQの新規キーワードとして、それも foreach をイメージできるような構文にして
"aggregate 売上帳" と書いたら、型名、その他をインテリセンスがズバズバッと書き出して、
作る側は中身をを書くだけといった具合になれば使えそうな気がするのですが……
もしくは Excel の、式のコピーのようなイメージができれば、やる事は一番上の式を書く事となるのですが。
130デフォルトの名無しさん
2008/02/28(木) 02:02:30 ところでこのコードってVB?
131デフォルトの名無しさん
2008/02/28(木) 11:52:14 驚くべきことに今まで一行もVBのコードは出てきていないんだ
132デフォルトの名無しさん
2008/02/28(木) 12:47:55 ほいじゃVB版Linq for XML
XMLリテラルが売りですのじゃ
Dim xm = <AAA>
<BBB id="1">aaaaacxzc</BBB>
<BBB id="2">aaaaaxczx</BBB>
<BBB id="3">aaaaaxcxz</BBB>
<BBB id="4">aaaaaxczx</BBB>
<BBB id="5">aaaaaxxxx</BBB>
<BBB id="6">aaaaazzzz</BBB>
<BBB id="7">aaaaacccc</BBB>
<BBB id="5">aaaaaxxxx</BBB>
<BBB id="6">aaaaazzzz</BBB>
<BBB id="7">aaaaacccc</BBB>
</AAA>
Dim rs = From x In xm...<BBB> _
Where x.@id > 2 _
Distinct Skip 1 Take 3 _
Order By x.@id Descending _
Select ID = x.@id, x
For Each r In rs
Console.WriteLine(r)
Next
XMLリテラルが売りですのじゃ
Dim xm = <AAA>
<BBB id="1">aaaaacxzc</BBB>
<BBB id="2">aaaaaxczx</BBB>
<BBB id="3">aaaaaxcxz</BBB>
<BBB id="4">aaaaaxczx</BBB>
<BBB id="5">aaaaaxxxx</BBB>
<BBB id="6">aaaaazzzz</BBB>
<BBB id="7">aaaaacccc</BBB>
<BBB id="5">aaaaaxxxx</BBB>
<BBB id="6">aaaaazzzz</BBB>
<BBB id="7">aaaaacccc</BBB>
</AAA>
Dim rs = From x In xm...<BBB> _
Where x.@id > 2 _
Distinct Skip 1 Take 3 _
Order By x.@id Descending _
Select ID = x.@id, x
For Each r In rs
Console.WriteLine(r)
Next
133デフォルトの名無しさん
2008/02/28(木) 13:15:08 クエリ式はC#よりVBの方が馴染んでるよなあ
VBのラムダ式は糞だけど
VBのラムダ式は糞だけど
134デフォルトの名無しさん
2008/02/28(木) 17:54:04 >>129
AggregateはSumやMaxと同じで集合関数として使うように設計されてるので
group by と組み合わせて使うのが普通なのだと思う。
この例だとSumが使えるのだがAggregateを使ってみた。
var 合計表 = (
from uri in 売上帳
group uri by 1 into g
select new 合計型(){
合計原価 = g.Sum(o => o.原価 * o.数量),
合計売価 = g.Aggregate(0, (t,o) => t + o.売価 * o.数量)
}).First();
Console.WriteLine("{0}, {1}", 合計表.合計原価, 合計表.合計売価);
AggregateはSumやMaxと同じで集合関数として使うように設計されてるので
group by と組み合わせて使うのが普通なのだと思う。
この例だとSumが使えるのだがAggregateを使ってみた。
var 合計表 = (
from uri in 売上帳
group uri by 1 into g
select new 合計型(){
合計原価 = g.Sum(o => o.原価 * o.数量),
合計売価 = g.Aggregate(0, (t,o) => t + o.売価 * o.数量)
}).First();
Console.WriteLine("{0}, {1}", 合計表.合計原価, 合計表.合計売価);
135デフォルトの名無しさん
2008/03/07(金) 01:17:17 C#なんだから大概の物は関数型チックにかくより普通に書いた方が
見やすいのは当たり前
見やすいのは当たり前
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- こども家庭庁、2026年から“独身税”を開始、年収200万なら年4200円、年収400万なら年7800円 [お断り★]
- 山里亮太、フィリピンに子ども食堂を建設 「偽善者」「日本の子どもを助けるべき」の声があっても活動を続ける理由 [Anonymous★]
- 鈴木農相「おこめ券はお米しか買えないわけではない。例えば卵、味噌、しょうゆ、こうした購入に利用可能」 ★3 [Hitzeschleier★]
- なぜリベラルは人気がないのか 斎藤幸平さんが指し示す未来への道筋:朝日新聞 ★4 [少考さん★]
- サナエノミクスについて力説 積極的な財政出動で「所得増える 消費マインド上がる 税収増える」片山さつき財務大臣 [少考さん★]
- 【芸能】粗品 「間違ったお笑いの常識が放送されている」「テレビ見てる素人って、笑い声でしか面白いかどうか判断できない。可哀想」 [冬月記者★]
- 他サポ2025-302
- 阪神競馬5回4日目 阪神JF
- 【NJPW】新日本プロレスワールド part.2431
- 第80回甲子園ボウル 立命館大学 vs 関西学院大学★1
- 中山競馬5回4日目その2カペラエス
- 中京競馬5回3日目
- 【悲報】日本人の「旅行離れ」が深刻化。愛国者は今すぐ旅行に行け! [834922174]
- 中国、日本人メンバーがいるK-POPアイドルの行事を中止 [329271814]
- ネット民「チー牛がフェミニストになりすまして草津町長を叩いていた」「フェミニストの正体は日本会議」「弱者男性が騒いでいた」 [932029429]
- 維新幹部「高市さん懇願します…解散しないように懇願します…」 [931948549]
- 【悲報】すまん何で日本ってこんなに反『中国』が増えたんだ?ネトウヨどころかそこらの一般人レベルでもゴロゴロいる [483447288]
- 鹿せんべいくれ
