hakeの日記

Windows環境でプログラミングの勉強をしています。

C# - LINQ

Enumerableなオブジェクトに対して様々な加工が可能である。面白いのは組み合わせて使用できること。
注意点としてはReserveメソッドのみ自身を書き換えること。試した範囲では他のメソッドは新規のEnumerableなオブジェクトを生成した。
 

using System;
using System.Collections.Generic;
using System.Linq;

//LINQ

class MyMain
{
    public static void Main(string[] args)
    {
        List<int> list = new List<int>(){1,10,2,9,3,8,4,7,5};
        
        //最後尾に追加
        PrintEnum( list.Append(6) );           //1 10 2 9 3 8 4 7 5 6
        list.Add(6);
        PrintEnum( list );                     //1 10 2 9 3 8 4 7 5 6
        //要素数
        Console.WriteLine( list.Count() );      //10
        //最初の要素
        Console.WriteLine( list.First() );      //1
        //最後の要素
        Console.WriteLine( list.Last() );       //6
        //全要素の平均値
        Console.WriteLine( list.Average() );    //5.5
        //最大値
        Console.WriteLine( list.Max() );        //10
        //最小値
        Console.WriteLine( list.Min() );        //1
        //合計
        Console.WriteLine( list.Sum() );        //55

        //並べ替え
        PrintEnum( list.OrderBy(e=>e) );              //1 2 3 4 5 6 7 8 9 10
        PrintEnum( list.OrderByDescending(e=>e) );    //10 9 8 7 6 5 4 3 2 1
        //逆順(自身を書き換え)
        list.Reverse();
        PrintEnum( list );                     //6 5 7 4 8 3 9 2 10 1

        //各要素を加工する
        PrintEnum( list.Select( e=>e+10 ) );   //16 15 17 14 18 13 19 12 20 11
        //index情報を追加
        PrintEnum( list.Select( (e,idx) => String.Format("{0}:{1}", idx, e) ) );
                                //0:6 1:5 2:7 3:4 4:8 5:3 6:9 7:2 8:10 9:1

        //畳み込み(初期値あり)
        Console.WriteLine( list.Aggregate(10, (sum,e) => sum + e ) );//65
        //畳み込み(初期値なし)
        Console.WriteLine( list.Aggregate((sum,e) => sum + e ) );    //55

        //最初から指定要素数を除外
        PrintEnum( list.Skip(5) );             //3 9 2 10 1
        //最初から条件を満たす要素までを除外
        PrintEnum( list.SkipWhile(e=>e!=9) );  //9 2 10 1
        //最初から指定要素数までを取得
        PrintEnum( list.Take(5) );             //6 5 7 4 8
        //最初から条件を満たす間の要素を取得
        PrintEnum( list.TakeWhile(e=>e!=9) );  //6 5 7 4 8 3

        //フィルタ
        PrintEnum( list.Where(e=> e%2==0) );   //6 4 8 2 10


        //組み合わせ
        //  偶数のうち最初の2つ
        PrintEnum( list.Where(e=> e%2==0).Take(2) );   //6 4
        //  奇数の合計
        Console.WriteLine( list.Where(e=> e%2==1).Sum() );//25


        //繰り返し
        IEnumerable<string> se = Enumerable.Repeat("A", 10);
        PrintEnum( se );   //A A A A A A A A A A

        //指定範囲の整数を生成
        IEnumerable<int> ie = Enumerable.Range(1, 5);
        PrintEnum( ie );   //1 2 3 4 5

        //全要素が条件を満たしているか
        ie = Enumerable.Range(3, 5);
        Console.WriteLine( ie.All(e=>e>2) );    //True
        Console.WriteLine( ie.All(e=>e>3) );    //False

        //条件を満たす要素があるか
        Console.WriteLine( ie.Any(e=>e==5) );    //True
        Console.WriteLine( ie.Any(e=>e==1) );    //False

        //要素があるか
        list = new List<int>();
        Console.WriteLine( list.Any() );         //False
        list.Add(1);
        Console.WriteLine( list.Any() );         //True


    }

    private static void PrintEnum(IEnumerable<int> a)
    {
        foreach(var e in a){ Console.Write("{0} ", e); }
        Console.WriteLine();
    }
    private static void PrintEnum(IEnumerable<string> a)
    {
        foreach(var e in a){ Console.Write("{0} ", e); }
        Console.WriteLine();
    }
}