【C#】List型(リスト型)をつかいこなそう #3

スポンサーリンク

リスト型を少しずつ使いこなしてきています。

今回はLINQ(リンク)という機能を使ってList型(リスト型)を使いこなしていきたいと思います。

List型(リスト型)ってなに?

配列の1種ですね!

一言でいうと「登録型配列」かなぁ~!

いや「可長配列」でもいいかもしれません🎵

 

世の中もので例えるとバインダー的なw

定義の仕方は

A4サイズの紙(型、構造体、クラス)しか入れない、

バインダー(リスト型)を定義するって感じです。

LINQ(リンク)とは

統合言語クエリ (Language INtegrated Query; LINQ, リンクと発音する) とは、.NET Framework 3.5において、様々な種類のデータ集合に対して標準化された方法でデータを問い合わせること(クエリ)を可能にするために、言語に統合された機能のことである。開発ツールはVisual Studio 2008から対応している。

統合言語クエリ – Wikipedia

ようは何?って感じですよね。。。w

便利な関数がいっぱいあるよ!と思ってくださいwww

実は、前回紹介している、最大値(MAX)や最小値(MIN)や合計(SUM)や平均(AVERAGE)は全てLINQの機能です🎵そう思うと、自然と使っていたんですね!

今回はほかにどんなLINQでどんなことができるかやってみたいと思います。

デフォルトでusingされているので覚えている必要はありませんが、

LINQを使う場合、usingが必要なので、usingを忘れないようにしてください。

using System.Linq;

LINQを使って型変換(配列→リスト/リスト→配列)

LINQを使った型変換で思いつくのは、「配列へ変換」or「配列から変換」です。

早速サンプルを作ってみましょう。

GUIをつくる

今回はシンプルにボタンを置いて、ボタンを押したら結果をテキストボックス(名前:txtResult)に表示するというようにします。

型変換(配列→List)

まずは配列からListに変換しようと思います。

【型変換(配列→LIST)】のボタンをクリックしたときの処理を作ります。

private void btnCast_Array2List_Click(object sender, EventArgs e)
{
    txtResult.Text = "";//初期化

    int[] arraySample = new int[] { 2, 4, 7, 3, 9, 4, 8, 6, 5, 0, 1 };

    //配列の内容をテキストボックスに表示
    txtResult.Text += "----- <Array> -----" + "\r\n";
    foreach (int i in arraySample)
    {
        txtResult.Text += i.ToString() + "\r\n";
    }

  //変換したリスト型をテキストボックスに表示
    List<int> array2list = arraySample.ToList();
    txtResult.Text += "----- <List> -----" + "\r\n";
    foreach (int a in array2list)
    {
        txtResult.Text += a.ToString() + "\r\n";
    }
}

ToString()みたいに配列の中にToList()って関数があるんですね!

結果はこんな感じになりました。まぁ当たり前ですが、ちゃんと変換されていそうですね!

型変換(List→配列)

次はListから配列に変換しようと思います。

【型変換(LIST→配列)】のボタンをクリックしたときの処理を作ります。

private void btnCast_List2Array_Click(object sender, EventArgs e)
{
    txtResult.Text = "";//初期化

    List<int> lstSampleInt = new List<int>();
    int[] num = new int[] { 2, 4, 7, 3, 9, 4, 8, 6, 5, 0, 1 };

    //数字を登録(追加)
    lstSampleInt.AddRange(num); 
    
  //リストの内容をテキストボックスに表示   
    txtResult.Text += "----- <List> -----" + "\r\n";
    foreach (int i in lstSampleInt)
    {
        txtResult.Text += i.ToString() + "\r\n";
    }

  //変換した配列の内容をテキストボックスに表示
    int[] list2array = lstSampleInt.ToArray();
    txtResult.Text += "----- <Array> -----" + "\r\n";
    foreach (int a in list2array)
    {
        txtResult.Text += a.ToString() + "\r\n";
    }       
}

リスト型には配列の時とは逆でToArray()という関数が準備されていました。

結果は、ちゃんと変換されていそうです。

LINQを使ってリストから要素を取得(抜き取る)

Linqを使えば要素を抜き取ることができます。

  • 重複を除外したリストを取得
  • 最初の要素から指定した要素分数除外したリストを取得する
  • 最初の要素から指定した要素数を取得する
  • 指定したインデックスから指定した要素数分取得する

早速、サンプルを作ってみます。

GUIを作成する

先ほどと同様に ボタンを押したら結果をテキストボックス(名前:txtResult)に表示するというようにします。

重複を除外したリストを取得

重複している要素を除外したいと思います。

今まで気づいていなかったのですが、4がかぶってました!w

private void btnDistinct_Click(object sender, EventArgs e)
{
    txtResult.Text = "";    //初期化

    //サンプル定義
    List<int> lstSampleInt = new List<int>() { 2, 4, 7, 3, 9, 4, 8, 6, 5, 0, 1 }; 

    //重複を除外
    List<int> lstDistinct = lstSampleInt.Distinct().ToList();

    //サンプルのリストの要素を表示
    txtResult.Text += "----- <OrgList> -----" + "\r\n";
    foreach (int i in lstSampleInt)
    {
        txtResult.Text += i.ToString() + "\r\n";
    }

    //重複除外後のリストの要素を表示
    txtResult.Text += "----- <DistinctList> -----" + "\r\n";
    foreach (int a in lstDistinct)
    {
        txtResult.Text += a.ToString() + "\r\n";
    }
}

重複を1行で除外できるなんて、、、なんて神関数なんだっっ!

無事に要素「4」を除外できていますね!

Distinct() を使ったとき、専用の型になっているので、リスト型に型変換してしてあげることを忘れずにしましょう。

最初のは残り、後から被ったものが除外される事は覚えておきましょう!

最初の要素から指定した要素分数除外したリストを取得する

指定した要素数分除外して、それ以降を取得したいと思います。

今回は最初の3つ分の要素は除外したリストを取得したいと思います。

private void btnSkip3_Click(object sender, EventArgs e)
{
    txtResult.Text = "";    //初期化

    //サンプル定義
    List<int> lstSampleInt = new List<int>() { 2, 4, 7, 3, 9, 4, 8, 6, 5, 0, 1 };   

    //最初の3つを除外
    List<int> lstSkip = lstSampleInt.Skip(3).ToList();

    //サンプルのリストの要素を表示
    txtResult.Text += "----- <OrgList> -----" + "\r\n";
    foreach (int i in lstSampleInt)
    {
        txtResult.Text += i.ToString() + "\r\n";
    }

    //除外後のリストの要素を表示
    txtResult.Text += "----- <SkipList> -----" + "\r\n";
    foreach (int a in lstSkip)
    {
        txtResult.Text += a.ToString() + "\r\n";
    }
}

最初の3つを除外し、除外された後のリストを表示ししました。

Skip()を使った戻り値は、専用の型なので、リスト型に変換しましょう!

最初の3つ【2,4,7】がなくなった状態になりましたね!

最初の要素から指定した要素数を取得する

指定した要素数分取得したいと思います。

今回は4つ分の要素を取得します。

private void btnTake4_Click(object sender, EventArgs e)
{
    txtResult.Text = "";    //初期化

    //サンプル定義
    List<int> lstSampleInt = new List<int>() { 2, 4, 7, 3, 9, 4, 8, 6, 5, 0, 1 };   

    //頭から4要素取得
    List<int> lstTake = lstSampleInt.Take(4).ToList();

    //サンプルのリストの要素を表示
    txtResult.Text += "----- <OrgList> -----" + "\r\n";
    foreach (int i in lstSampleInt)
    {
        txtResult.Text += i.ToString() + "\r\n";
    }

    //取得したリストの要素を表示
    txtResult.Text += "----- <TakeList> -----" + "\r\n";
    foreach (int a in lstTake)
    {
        txtResult.Text += a.ToString() + "\r\n";
    }
}

最初の要素4つ分を取得し表示ししました。

Take()を使った戻り値は、専用の型なので、リスト型に変換しましょう!

最初の4つ【2,4,7、3】を取得することができました。

指定したインデックスから指定した要素数分取得する

これは、先ほどの最初の要素を除外する(Skip)と要素数分取得する(Take)の合わせ技です。

最初の3つの要素を除外して、それから4つ分の要素を取得しましょう。

早速サンプルを作ります。

private void btnSkip3Take4_Click(object sender, EventArgs e)
{
    txtResult.Text = "";    //初期化

  //サンプル定義
    List<int> lstSampleInt = new List<int>() { 2, 4, 7, 3, 9, 4, 8, 6, 5, 0, 1 };

    //最初の3つをスキップして、そのあと4つ分を取得する。
    List<int> lstSkipTake = lstSampleInt.Skip(3).Take(4).ToList();

    //サンプルのリストの要素を表示
    txtResult.Text += "----- <OrgList> -----" + "\r\n";
    foreach (int i in lstSampleInt)
    {
        txtResult.Text += i.ToString() + "\r\n";
    }

    //取得したリストの要素を表示
    txtResult.Text += "----- <SkipTakeList> -----" + "\r\n";
    foreach (int a in lstSkipTake)
    {
        txtResult.Text += a.ToString() + "\r\n";
    }
}

最初の3つを除外して、それ以降4つの要素を取得しました。

結果として【3,9,4,8】を取得することができましたね。

注意事項は、リスト型への変換を忘れないことSkipとTakeの順番を間違えないことです。

まとめ

Linqを覚えているとすごく便利です。紹介できている内容も、Linqの一部でしかありません。

ほかにもいっぱい準備されていますが、個人的にはすべてを覚える必要はないと思います。

覚えることはよく使うモノで、他は調べて使えればいいと思います。記憶にも限界はありますし。。。

今回紹介した内容は、【型変換】【重複の除外】【指定Indexから取得】【指定要素数分の取得】【指定Indexから指定要素数分までの取得】でした。

自分的によく使うのは、【指定Indexから指定要素数分】までの取得です。

自分がリスト型を使うのはCSV読み込みとの組み合わせが多く、ある行からある行(要素数分)で取得したいときに使います。

Linqを知っているとコードもスマートになるのでいいと思います。

ただしデメリットとして、読みづらくなります。(自分がではなく、相手にとって)

価値観はそれぞれですが、使えないよりは使えた方がいいので、使いこなすことをオススメはします。

コメント

タイトルとURLをコピーしました