ここではC#の以下のListクラスについて操作の方法を解説します。とても簡単なコードで網羅的に説明しています。
Listと配列
List(List<T>クラス)と似たものに配列(Arrayクラス)があります。Listも配列も複数のデータを格納したり取り出したりする用途に使われます。配列もListも要素番号(インデックス)で要素にアクセスすることができます。
大きな違いは、配列は要素数が一定である場合に使われるのに対して、Listは要素数が変更される場合に使われることです。このため、Listには、配列にはない、要素を追加・削除できるメソッドが実装されています。配列も要素数を増やしてコピーして、増やした要素に値を入れるなどすれば(無理やり)要素数を増やすこともできますが、要素数が変わる場合には無理して配列を使う必要はなくListを使ったほうがよいでしょう。
- 要素数が変わる場合にはListを使う
- 要素数が固定の場合には配列を使う
Listの宣言と初期化
まずはListの宣言と初期化を見てみます。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
//宣言①
List<string> lst1 = new List<string>(); //要素数0
//宣言②
List<string> lst2 = new List<string> { "A","B","C"}; //文字列A,B,Cで初期化
//宣言③
var lst3 = new List<string>{ "A", "B", "C" }; //型推論
}
}まずList<T>クラスを使用するため、usingディレクティブに
using System.Collections.Generic;が必要です。書かない場合には宣言時に完全修飾名が必要です。
次に宣言ですが、List<T>のTの部分は、Listとして取り扱う要素の型名が入ります。上記の9行目および11行目の例ではstring型のListを宣言しているので、List<string>としています。また、要素数0で初期化する場合には9行目のとおり、他のクラス同様にnew List<string>()のように最後にカッコを付けます。
宣言と同時に値を指定して初期化する場合には11行目のように{}内で初期値を指定します。ここでは文字列”A”,”B”,”C”で初期化しています。
13行目のように型推論を用いて宣言することも可能です。型推論を用いることで冗長な表現を避けることができます。
Listの要素の取得・追加・挿入・削除
要素番号による値の取得・上書きとCountプロパティによる要素数の取得
Listの値を取得するときは、配列と同じようにList変数名[要素番号]で、その要素番号の値にアクセスすることができます。要素番号は0から始まる正数です。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string> { "Japan", "USA", "Canada" };
Console.WriteLine("Count:{0}", lst.Count);
for (int i = 0; i < lst.Count; i++)
{
Console.WriteLine("lst[{0}]:{1}", i, lst[i]);
}
lst[1] = "United States";
foreach (var item in lst)
{
Console.WriteLine(item);
}
}
}出力結果
Count:3
lst[0]:Japan
lst[1]:USA
lst[2]:Canada
Japan
United States
Canada
上記コードの9行目でCountプロパティで要素数を取得しコンソールに表示しています。ここでは要素数は3となっています。要素数の取得は、配列とは違うので注意しましょう(配列の要素数はLengthプロパティで取得します)。 11~14行目のfor文では要素番号でlstの要素を取得し列挙しています。
また16行目のように要素番号を指定して値の設定(書き換え)も可能です。
列挙するだけなら、18~21行目のようにforeach文を使ってもいいでしょう。
Addメソッドによる要素の追加
Listへの要素の追加を見てみましょう。要素の追加はAddメソッドで行います。AddメソッドではListの末尾に要素を追加します。Addメソッドの引数は、追加する要素の値です。戻り値はありません。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string>(); //空のList
lst.Add("Japan"); //要素を追加
lst.Add("USA"); //要素を追加
lst.Add("Canada");//要素を追加
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
}
}出力結果
lst:[Japan USA Canada]
上記コードの10~12行目のようにAddメソッドでListの末尾に要素を追加できます。ここでは、”Japan”, “USA”, “Canada”を追加しました。結果は14行目で出力されています。
AddRangeメソッドによる複数要素の追加
次に複数の要素を追加してみましょう。複数の要素を追加する場合には、AddRangeメソッドを使います。AddRangeメソッドでは、Listの末尾に複数の要素を追加します。AddRangeメソッドの引数は追加する要素のコレクション(Listや配列)です。 戻り値はありません。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string>(); //空のList
//Listを追加
var lstAsia = new List<string> { "Japan", "China", "Vietnam" };
lst.AddRange(lstAsia);
//配列を追加
var arrAmerica = new string[] { "USA", "Canada" };
lst.AddRange(arrAmerica);
//直接追加する場合
lst.AddRange(new List<string>{"France", "Italy"});
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
}
}出力結果
lst:[Japan China Vietnam USA Canada France Italy]
11~12行目では空のLsitに別のListの内容を追加しています。15~16行目のように配列を追加することもできます。また直接、値を追加する場合には19行目のようにします。いずれも、Listの末尾に追加されます。
Insertメソッドによる要素の挿入
AddメソッドおよびAddRangeメソッドはListの末尾へ要素を追加しましたが、Insertメソッドは要素番号を指定して任意の位置に要素を追加できます。Insertメソッドの引数は挿入する位置の要素番号と挿入する要素の値です。戻り値はありません。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string> { "USA", "Canada", "France", "Vietnam" };
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
lst.Insert(0, "Japan"); //先頭に追加
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
lst.Insert(lst.Count, "Mexico"); //末尾に追加
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
lst.Insert(3, "Brazil"); //要素番号3の位置に追加
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
}
}出力結果
lst:[USA Canada France Vietnam]
lst:[Japan USA Canada France Vietnam]
lst:[Japan USA Canada France Vietnam Mexico]
lst:[Japan USA Canada Brazil France Vietnam Mexico]
上記コード11行目では、Listの先頭に要素”France”を追加しています。13行目では、Listの末尾に要素”Mexico”を追加しています。末尾に追加する場合の結果はAddメソッドと同じです。17行目では要素番号3の位置に要素”Brazil”を追加しています。
InsertRangeメソッドによる複数要素の挿入
InsertRangeメソッドでは挿入位置を指定して複数の要素をListに挿入できます。Insertメソッドの引数は追加する要素番号と追加する要素のコレクション(Listや配列)です。戻り値はありません。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string> { "Japan", "China", "Vietnam" }; //空のList
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
//Listを追加
var lstAsia = new List<string> { "India", "Thailand" };
lst.InsertRange(0, lstAsia); //先頭に追加
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
//配列を追加
var arrAmerica = new string[] { "USA", "Canada" };
lst.InsertRange(lst.Count, arrAmerica); //末尾に追加
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
//直接追加する場合
lst.InsertRange(3, new List<string> { "France", "Italy" }); //要素番号3の位置に追加
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
}
}出力結果
lst:[Japan China Vietnam]
lst:[India Thailand Japan China Vietnam]
lst:[India Thailand Japan China Vietnam USA Canada]
lst:[India Thailand Japan France Italy China Vietnam USA Canada]
上記コードの12~13行目では要素の先頭にListを追加しています。17~18行目ではリストの末尾に配列を追加しています。これはAddRangeと同じ結果となります。22行目では直接複数の値を要素番号3の位置に追加しています。このようにInsertRangeメソッドの動作は、AddRangeのInsert版のような動作なのでわかりやすいでしょう。
Removeメソッドによる要素の削除
指定の値の要素を削除する場合にはRemoveメソッドを使用します。Removeメソッドは引数に削除する要素の値を指定します。戻り値はbool型で、要素が正常に削除されたときにはtrueを返し、それ以外のときにはfalseを返します。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string> { "USA", "Japan", "Canada" };
lst.AddRange(new List<string> { "Japan", "Vietnam" });
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
bool result;
result = lst.Remove("Japan");
Console.WriteLine("result:{0}",result);
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
result = lst.Remove("France");
Console.WriteLine("result:{0}", result);
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
}
}出力結果
lst:[USA Japan Canada Japan Vietnam]
result:True
lst:[USA Canada Japan Vietnam]
result:False
lst:[USA Canada Japan Vietnam]
上記の例では14行目で”Japan”を削除しています。この例ではリストに”Japan”は2つ含まれていますが、このような場合には要素番号の小さいほうを削除します。上記のコードの例では14行目では”Japan”が削除されたのでtrueを返し、18行目ではリストにはない”France”を削除しようとしたので削除できずfalseを返しています。
RemoveAtメソッドによる値の削除(要素番号指定)
要素番号を指定して要素を削除するときにはRemoveAtメソッドを使用します。戻り値はありません。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string> { "USA", "Japan", "Canada", "France", "Vietnam" };
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
lst.RemoveAt(3);
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
}
}
出力結果
lst:[USA Japan Canada France Vietnam]
lst:[USA Japan Canada Vietnam]
上記のコードの例では、要素番号3の値、すなわち”Japan”を削除しています。
RemoveRangeメソッドによる指定範囲の要素の削除
要素を指定した範囲で削除するにはRemoveRangeメソッドを使用します。RemoveRangeメソッドの引数は削除する範囲の最初の要素番号と削除する要素数の2つです。戻り値はありません。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string> { "Japan", "China", "Vietnam", "India", "USA", "Canada","Mexico","France","Italy" }; //空のList
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
lst.RemoveRange(2,3); //要素番号2から3つの要素を削除
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
lst.RemoveRange(0, lst.Count); //すべての要素を削除
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
}
}出力結果
lst:[Japan China Vietnam India USA Canada Mexico France Italy]
lst:[Japan China Canada Mexico France Italy]
lst:[]
上記コードの11行目では要素番号2から3つの要素を削除しています。すなわち、”Vietnam”, “India”, “USA”が削除されています。14行目では要素番号0から要素数Count分、すなわちすべての要素を削除しています。
RemoveAllメソッドによる指定条件による削除
RemoveAllメソッドは、ある条件に該当する要素をすべて削除したい場合に用います。RemoveAllメソッドの引数には削除する要素の条件を定義するPredicate<T>デリゲートが指定されます。ラムダ式で指定することが多いようです。戻り値はint型で削除された要素数を返します。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string> { "Japan", "Vietnam", "India", "USA", "Canada", "Mexico" };
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
int rm = lst.RemoveAll(item => item.Contains("a"));
Console.WriteLine("{0}個の要素が削除されました.", rm);
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
}
}出力結果
lst:[Japan Vietnam India USA Canada Mexico]
4個の要素が削除されました.
lst:[USA Mexico]
上記の例では、11行目でRemoeAllメソッドの引数としてラムダ式で文字列”a”を含む条件を指定していますので、”a”が含まれた要素すべてが削除されています。また削除した要素数も変数rmとして取得しています。なお、ここで用いているContainsはstring型のContainsメソッドであり、ListのContainsメソッドではありませんのでご注意ください。
Clearメソッドによる要素の全削除
Clearメソッドでは、要素をすべて削除することができます。Clearメソッドに引数も戻り値もありません。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string> { "Japan", "Vietnam", "India", "USA", "Canada","Mexico" }; //空のList
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
lst.Clear();
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
}
}出力結果
lst:[Japan Vietnam India USA Canada Mexico]
lst:[]
上記コードでは11行目でClearメソッドを使用しており、すべての要素が削除されています。
Listの検索・逐次処理・ソート
IndexOfメソッドによる要素番号の取得
IndexOfメソッドは指定の値を検索して、戻り値として、その要素番号を取得します。IndexOfメソッドの引数には、検索する値を指定します。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string> { "USA", "Japan", "Canada" };
lst.AddRange(new List<string> { "Japan", "Vietnam" });
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
Console.WriteLine("Japan Index:{0}", lst.IndexOf("Japan"));
Console.WriteLine("France Index:{0}", lst.IndexOf("France"));
}
}出力結果
lst:[USA Japan Canada Japan Vietnam]
Japan Index:1
France Index:-1
このコードの例ではリストには”Japan”が要素番号1と3に2つ含まれています。IndexOfメソッドは、12行目のように”Japan”が含まれる最初の要素番号を返します。すなわち指定した値が複数ある場合には最初の要素番号を返します。また、13行目の”France”のようにリストに含まれていない値が引数のときにはIndexOfメソッドは-1を返します。
Containsメソッドで値が含まれるかを調べる方法
Containsメソッドを使用すると、Listに指定した値が含まれているかを判定することができます。Cotainsメソッドの引数には含まれているかを判定したい値を指定し、bool型の戻り値を返します。その値が含まれているときContainsメソッドはtrueを返し、含まれていないときにはfalseを返します。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string> { "Japan", "Vietnam", "India", "USA", "Canada","Mexico" }; //空のList
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
bool result;
result = lst.Contains("India");
Console.WriteLine("result:{0}", result);
result = lst.Contains("China");
Console.WriteLine("result:{0}", result);
}
}出力結果
lst:[Japan Vietnam India USA Canada Mexico]
result:True
result:False
上記のコードの例では、13行目では”India”が含まれているかを判定しています。”India”はListに含まれていますのでTrueを返します。16行目では”China”が含まれているかを判定しており、含まれていないのでFalseを返します。
Find, FindLastメソッドによる値の検索
Findメソッドでは指定した条件の値を検索し、戻り値として最初に該当した値を返します。FindLastメソッドは、同じく最後に該当した値を戻り値として返します。両方とも引数は 検索する値の条件を定義するPredicate<T>デリゲートが指定されます。もし該当がする値がなかった場合には、戻り値として要素のデータ型(T型)の既定値を返します。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string> { "Mexico", "Japan", "USA", "Canada", "Mexico" };
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
string result;
result = lst.Find(item => item.Contains("a"));
Console.WriteLine("result(Find):{0}", result);
result = lst.FindLast(item => item.Contains("a"));
Console.WriteLine("result(FindLast):{0}", result);
}
}出力結果
lst:[Mexico Japan USA Canada Mexico]
result(Find):Japan
result(FindLast):Canada
上記コードでは13行目のFindメソッドの引数として、ラムダ式で”a”が含まれる値かどうかを条件としています。この結果、Findメソッドは”a”の含まれる最初の要素である”Japan”を返しています。同じく16行目のFindLastメソッドでは”a”の含まれる最後の要素である”Canada”を返しています。
FindIndex, FindLastIndexメソッドによる要素番号の検索
FindIndexメソッドは、Findメソッドと同様に指定した条件の値を検索し、最初に該当した値の要素番号を返します。FindLastメソッドは、同じく最後に該当した値の要素番号を返します。両方とも引数は 検索する値の条件を定義するPredicate<T>デリゲートが指定されます。 該当がない場合には戻り値は-1になります。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string> { "Mexico", "Japan", "USA", "Canada", "Mexico" };
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
int result;
result = lst.FindIndex(item => item.Contains("a"));
Console.WriteLine("result(Find):{0}", result);
result = lst.FindLastIndex(item => item.Contains("a"));
Console.WriteLine("result(FindLast):{0}", result);
}
}出力結果
lst:[Mexico Japan USA Canada Mexico]
result(Find):1
result(FindLast):3
上記コードでは13行目のFindIndexメソッドの引数として、ラムダ式で”a”が含まれる値かどうかを条件としています。この結果、FindIndexメソッドは”a”の含まれる最初の要素である”Japan”の要素番号である1を返しています。同じく16行目のFindLastIndexメソッドでは”a”の含まれる最後の要素である”Canada”の要素番号である3を返しています。
FindAllメソッドによる全要素の検索
FindAllメソッドでは、 指定した条件の値を検索し該当したすべての値をリストとして返します。 引数は 検索する値の条件を定義する Predicate<T> デリゲートが指定されます。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string> { "Mexico", "Japan", "USA", "Canada", "Mexico" };
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
List<string> result;
result = lst.FindAll(item => item.Contains("a"));
Console.WriteLine("{0}:[{1}]", nameof(result), string.Join(" ", result));
}
}出力結果
lst:[Mexico Japan USA Canada Mexico]
result:[Japan Canada]
上記コードでは12行目で、”a”を含むすべての要素を取得しています。この結果、”a”が含まれる”Japan”と”Canada”を要素としたListが返されています。
ForEachメソッドによる逐次処理
Listには逐次処理のためのForEachメソッドが用意されています。ForEachメソッドの引数にはListの各要素に対して実行するデリゲートを指定します。通常はラムダ式による無名関数を指定します。
コード
internal class Program
{
static void Main(string[] args)
{
var lst = new List<int> {1,4,8,11,14,19,21,26 }; //空のList
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst)); //リストの表示
lst.ForEach(item =>
{
if(item%2==0)
Console.WriteLine(item);
});
}
}出力結果
lst:[1 4 8 11 14 19 21 26]
4
8
14
26
上記コードでは、int型のListに対して8~12行目でForEachメソッドを用いて偶数のみをコンソールに出力しています。
SortメソッドによるListのソート
ListはSortメソッドで値をソートすることができます。Sortメソッドは、引数としてComparison<T> デリゲートを指定します。Sortメソッドに戻り値はありません。引数を省略した場合には、規定の比較子でソートされます。通常、昇順でソートする場合には引数を省略します。 Comparison<T> デ リゲートは同じ型の 2 つのオブジェクトを比較するメソッドを表します。Sortメソッドの後にはListはソートされたものに置き換わるので注意が必要です。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<int> { 5, 1, 8, 11, 3, 13, 26, 9, 10 };
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
lst.Sort();
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
lst.Sort((a, b) => b - a);
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
}
}出力結果
lst:[5 1 8 11 3 13 26 9 10]
lst:[1 3 5 8 9 10 11 13 26]
lst:[26 13 11 10 9 8 5 3 1]
上記コードの11行目のSortメソッドでは引数を省略していますので、昇順でソートされています。14行目では、ラムダ式で(a,b)=>b-a を引数にしているので、降順でソートされています。
Listの変換
ConvertAllメソッドによるListの型変換
Listの型を変換するときにはConvertAllメソッドを使用します。ConvertAllメソッドの引数には、Converter<TInput,TOutput>デリゲートを指定します。戻り値は型変換されたListです。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lstChar = new List<char> { 'a', 'b', 'c', 'd' };
Console.WriteLine("{0}:[{1}]", nameof(lstChar), string.Join(" ", lstChar)); //リストの表示
List<int> lstInt = lstChar.ConvertAll(item => (int)item);
Console.WriteLine("{0}:[{1}]", nameof(lstInt), string.Join(" ", lstInt)); //リストの表示
}
}出力結果
lstChar:[a b c d]
lstInt:[97 98 99 100]
上記コードの11行目のConvertAllメソッドで、char型の要素を持つListをint型の要素を持つListに変換しています。ConvertAllメソッドの引数には、要素をint型に型変換する Converter<TInput,TOutput>デリゲートをラムダ式で指定しています。
ToArrayメソッドでListを配列に変換する
Listを配列に変換するには、ListのToArrayメソッドを使用します。ToArrayメソッドに引数はなく、戻り値は変換された配列オブジェクトです。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var lst = new List<string> { "Japan", "USA", "Canada" };
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
string[] arr = lst.ToArray();
Console.WriteLine("{0}:[{1}]", nameof(arr), string.Join(" ", arr));
}
}出力結果
lst:[Japan USA Canada]
arr:[Japan USA Canada]
上記コードでは、11行目のToArrayメソッドでListを配列に変換してarrに代入しています。
ToListメソッドで配列をListに変換する
配列をListに変換するにはToList<T>メソッドを使用します。なお、ToListメソッドはLINQのメソッドのため、usingディレクティブに、
using System.Linq;が必要です。
ToListメソッドに引数はなく、戻り値は変換されたListオブジェクトです。
コード
using System;
using System.Collections.Generic;
using System.Linq;
internal class Program
{
static void Main(string[] args)
{
var arr = new string[] { "Japan", "USA", "Canada" };
Console.WriteLine("{0}:[{1}]", nameof(arr), string.Join(" ", arr));
List<string> lst = arr.ToList<string>() ;
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
}
}出力結果
arr:[Japan USA Canada]
lst:[Japan USA Canada]
上記の例では12行目で配列をListに変換してlstに代入しています。3行目で、using System.Linq; を追記しています。
Listを配列で初期化することで配列をListに変換する
Listの宣言・初期化時に配列で初期化することができます。これを用いれば配列をListに変換できます。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var arr = new string[] { "Japan", "USA", "Canada" };
Console.WriteLine("{0}:[{1}]", nameof(arr), string.Join(" ", arr));
List<string> lst = new List<string>(arr);
Console.WriteLine("{0}:[{1}]", nameof(lst), string.Join(" ", lst));
}
}出力結果
arr:[Japan USA Canada]
lst:[Japan USA Canada]
上記コードでは、11行目でListのコンストラクタの引数として配列を指定することで、配列をListに変換しています。
多次元List
ここではListを多次元で扱う方法について解説します。例えば2次元Listでは、List<List<int>>のようにListを入れ子にして宣言します。3次元Listではさらに入れ子を増やし、List<List<Lit<int>>>のようにします。以下に2次元と3次元の例を示します。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
//2次元Listの宣言
var lst2D = new List<List<int>> { new List<int> { 1, 2, 3 }, new List<int> { 4, 5, 6 }, new List<int> { 7, 8, 9 } };
//2次元Listの表示
for (int i = 0; i < lst2D.Count; i++)
{
for (int j = 0; j < lst2D[i].Count; j++)
{
Console.WriteLine("lst2D[{0}][{1}]:{2}", i, j, lst2D[i][j]);
}
}
//3次元Listの宣言
var lst3D = new List<List<List<int>>>();
//3次元Listへの値の追加
for (int i = 0; i < 3; i++)
{
lst3D.Add(new List<List<int>>());
for (int j = 0; j < 4; j++)
{
lst3D[i].Add(new List<int>());
for (int k = 0; k < 5; k++)
{
lst3D[i][j].Add(i + j + k);
}
}
}
//3次元Listの表示
for (int i = 0; i < lst3D.Count; i++)
{
for (int j = 0; j < lst3D[i].Count; j++)
{
Console.WriteLine("lst3D[{0}][{1}]:[{2}]", i, j, string.Join(" ", lst3D[i][j]));
}
}
}
}出力結果
lst2D[0][0]:1
lst2D[0][1]:2
lst2D[0][2]:3
lst2D[1][0]:4
lst2D[1][1]:5
lst2D[1][2]:6
lst2D[2][0]:7
lst2D[2][1]:8
lst2D[2][2]:9
lst3D[0][0]:[0 1 2 3 4]
lst3D[0][1]:[1 2 3 4 5]
lst3D[0][2]:[2 3 4 5 6]
lst3D[0][3]:[3 4 5 6 7]
lst3D[1][0]:[1 2 3 4 5]
lst3D[1][1]:[2 3 4 5 6]
lst3D[1][2]:[3 4 5 6 7]
lst3D[1][3]:[4 5 6 7 8]
lst3D[2][0]:[2 3 4 5 6]
lst3D[2][1]:[3 4 5 6 7]
lst3D[2][2]:[4 5 6 7 8]
lst3D[2][3]:[5 6 7 8 9]
上記コードの例では9行目で2次元Listを宣言しています。値を取得するには16行目のようにList名[i][j]で取得します。
21行目では空の3次元配列を宣言し、24~35行目で値を追加しています。値を取り出すには、2次元Listと同じようにList名[i][j][k]で取得します。
配列でできてListでできないこと
下記のように配列要素を参照渡しでメソッドに渡すことはできますが、Listの要素を参照渡しでメソッドに渡すことはできません。
コード
using System;
using System.Collections.Generic;
internal class Program
{
static void Main(string[] args)
{
var arr = new string[] { "Japan", "USA", "Canada" };
ChangeValue(ref arr[1]);
Console.WriteLine("{0}:[{1}]", nameof(arr), string.Join(" ", arr));
List<string> lst = new List<string>() { "Japan", "USA", "Canada" };
//ChangeValue(ref lst[1]); //これはエラー
}
static void ChangeValue(ref string val)
{
val = "Mexico";
}
}出力結果
arr:[Japan Mexico Canada]
上記コードの9行目のように配列の要素を参照渡しのメソッドに渡すと要素の値が変更されます。しかしListの場合には13行目にコメントアウトしたような処理はできません。エラーとなります。
終わりに
この記事では、Listの操作全般についてまとめました。簡単なコードで事例を示したので、ゆっくり動作確認してみてください。

