【ワテのC#講座】今日覚えたC#の小技【LINQマニア】

この記事は約9分で読めます。
スポンサーリンク

まあ、あくまで自分用の備忘録であるが、今日覚えたC#の小技をメモしておく。

ワテの場合、C#をやり始めたのは10数年くらい前か。

VB.NETはさらに数年前。

最近のC#はいろんな手法が使えるので、ワテには全部は覚えきれない。

ちなみに最近ではLINQに凝っている。

以前は、LINQを見ると蕁麻疹が出るくらい拒絶反応が有ったのだが、その後、猛烈にLINQを勉強した。

そうすると、配列やリストに対してちょっとしたループ処理をしたい場合に、オーソドックスな foreach や for(int i=0; … などのループを使うと何だか負けた気分。

どうにかしてLINQで一行で書けると、充実感がある。

まさにLINQ中毒。

 

スポンサーリンク
ワテ推薦のプログラミングスクールで学ぶ
スポンサーリンク
スポンサーリンク

今日覚えたC#の小技

月末の日にちを求める方法

DateTimeを使うと日時の処理が可能だ。

月の始めは1日からだが、では、月末の日にちを取得するにはどうするか?

例えば 2017年3月 の月末は何日か?

そう言う場合には、以下のようにすると取得出来る。

var dtSta = new DateTime(2017, 3, 1); 
var dtEnd = new DateTime(2017, 3, DateTime.DaysInMonth(2017, 3));
var dtEndDay = dtEnd.Date.Day;  // 31

これで2017年3月の月末が31日で有る事が分る。

 

DateTimeの中から曜日プロパティを数字で得るには?

DayOfWeekプロパティでその日が何曜日なのか分る。

例えば日曜日の場合には、それを整数で求めるにはどうするか?

intにキャストすれば良い。

var dayofweek1 = dtSta.DayOfWeek;           // Sunday
int dayofweek2 = (int)dtSta.DayOfWeek;      // 0

 

二次元配列の各次元のサイズの求め方

こんな感じか。

  var twoDimArr = new int[2, 3];
  var dim1 = twoDimArr.GetLength(0); //  1次元目のサイズ = 2
  var dim2 = twoDimArr.GetLength(1); //  2次元目のサイズ = 3

 

ASP.NET MVCのRazorでModelの型を明示的に指定したい場合

例えば index.cshtml の冒頭で、以下の様に宣言すると良い。

@model List<string>

この例では List<string> で宣言している。

 

List<T> をn個ずつに分割し Enumerable<List<T>>作るには?

こんな感じか。

public static IEnumerable<List<T>> splitList<T>(List<T> locations, int nSize )
{
    for (int i = 0; i < locations.Count; i += nSize)
    {
        yield return locations.GetRange(i, Math.Min(nSize, locations.Count - i));
    }
}

使い方としては、こんな感じか。

IEnumerable<List<string>> stringLstLst = splitList<string>(stringLst, 7);

必要ならこの後、toList() して List<List<string>> にしても良い。

 

List<T> にn個の要素を追加するには?

例えば MyClass と言うクラスを作って、そのクラス型のList型の変数 myClassLst を作成した。

そこに10個の要素を追加する場合はこんな感じか。

var myClassLst = new List<MyClass>();
myClassLst.AddRange(Enumerable.Repeat(new MyClass(), 10));

 

List<List<T>>をList<T>に平坦化(Flatten)するには?

例えば List<List<string>> のデータ strLstLst があるとする。

	var strLstLst = new List<List<string>>
	{
		new List<string>(){"00","01","02","03"},
		new List<string>(){"10","11","12","13"},
		new List<string>(){"20","21","22","23"},
		new List<string>(){"30","31","32","33"},
		new List<string>(){"40","41","42","43"},
	};

こんなデータだ。

 

それを List<string> の形式に変換したい。

もし普通にforループで処理するなら、こんな感じか。

var strLst2 = new List<string>();
foreach (var strLst in strLstLst)
{
	strLst2.AddRange(strLst);
}

つまりまあAddRangeで結合して行けば良い。

 

それをLINQでやってみる。

メソッド構文とクエリ構文の二種類をやってみた。

class Program
{
	static void Main(string[] args)
	{
		var strLstLst = new List<List>
		{
			new List(){"00","01","02","03"},
			new List(){"10","11","12","13"},
			new List(){"20","21","22","23"},
			new List(){"30","31","32","33"},
			new List(){"40","41","42","43"},
		};
                // LINQ メソッド構文
		var strLst1 = strLstLst.SelectMany(d => d).ToList();

                // LINQ クエリ構文
		var strLst3 =
			(from strLst in strLstLst
			 from str in strLst
			 select str).ToList()
			;
	}
}

こんな感じか。

LINQメソッド構文でやる場合にはSelectManyを使うと簡単に出来る。

と言うか、ワテの場合SelectManyの使い方を十分理解出来ていないので、SelectManyを使う場面と言うのはこんなのしか思いつかない。

一方、LINQクエリ構文でやる場合には、fromを二回使えば出来た。

それを.ToList() でリスト化している。

なお、メソッド構文の場合、SelectManyを使えば簡単だが、それを使わずにSelectのみを使ってFlatten出来るのかどうかは未確認だ。

少し試してみたのだが、ワテの能力不足が原因で、出来なかった。

もし出来る人がいたら教えて下さい。

SelectManyで平坦化の例その2

SelectMayでList<string>を平坦化(flatten)する二番目の例を考えてみた。

例えばこんなデータがあるとしよう。

[都道府県名1] [都市名11], [都市名12], [都市名13] 
[都道府県名2] [都市名21], [都市名22]
[都道府県名3] [都市名31], [都市名32], [都市名33] 

それを

[都道府県名1] [都市名11]
[都道府県名1] [都市名12]
[都道府県名1] [都市名13]
[都道府県名2] [都市名21]
・・・

のように展開したい。

さっそくメソッド構文LINQで書いてみた。

class SelectManyの例2
{
	public static void test1()
	{
		var 自治体リスト = new Dictionary<string, List>();
		自治体リスト.Add("東京都", new List() { "目黒区", "三鷹市", "四条畷市" });
		自治体リスト.Add("大阪府", new List() { "中央区", "枚方市" });
		自治体リスト.Add("沖縄県", new List() { "那覇市", "国頭郡", "宜野湾市" });

		var result = new List<Tuple<string, string>>();
		foreach (var 自治体_i in 自治体リスト)
		{
			foreach (var detail in 自治体_i.Value)
			{
				result.Add(new Tuple<string, string>(自治体_i.Key, detail));
			}
		}
		result.ForEach(line => Console.WriteLine("->{0}<- ->{1}<-", line.Item1, line.Item2));
	}
 
}

こんな感じか。

 

早速実行してみる。

実行結果

->東京都<- ->目黒区<-
->東京都<- ->三鷹市<-
->東京都<- ->四条畷市<-
->大阪府<- ->中央区<-
->大阪府<- ->枚方市<-
->沖縄県<- ->那覇市<-
->沖縄県<- ->国頭郡<-
->沖縄県<- ->宜野湾市<-

続行するには何かキーを押してください . . .

ええ感じや。

あれ?

四条畷市(しじょうなわて)は大阪だった。

それと、枚方市は「まきかたし」では無くて「ひらかたし」と読む。

マメ知識でした。

 

LINQはとても便利だ。

LINQを敬遠している人は使ってみると良いだろう。

使えば使う程手軽で便利。

LINQで書くと、あとで見なおしたら何しているのか分からないなとと言う意見もあるが、それは慣れの問題。

例えば今回利用したSelectManyも、このような場面で使える事を記憶しておけば、あとで見直した場合に直ぐにやっている内容を思い出せるのだ。

皆さんにお勧めしたい。

 

今後、新しい豆知識を習得したら、随時ここに追加して行きたい。

C#の本を読む

LINQを敬遠している人は、騙されたと思ってLINQに挑戦してみると良い。

ワテもLINQは食わず嫌いだったのだが、今では、LINQ無しではプログラムが書けないくらいのLINQ中毒だ。

スポンサーリンク
ワテ推薦のプログラミングスクールで学ぶ
コメント募集

この記事に関して何か質問とか補足など有りましたら、このページ下部にあるコメント欄からお知らせ下さい。

C#
スポンサーリンク
warekoをフォローする
スポンサーリンク
われこ われこ

コメント