c# 配列 メソッド一覧

#初めに

忘備録としてc#の配列操作についてまとめます。

とりあえずドキュメントに乗ってる配列操作すべてに触れてみました。

大体こちら↓を参考にしています。

https://docs.microsoft.com/ja-jp/dotnet/api/system.array?view=netframework-4.8



# AsReadOnly

これは配列をreadOnlyにするもの


* 例

```c#
        static void Main(string[] args)
        {
            string[] notReadOnlyArray = new string[] { "first", "second", "third" };
            notReadOnlyArray[0] = "first update";
            Console.WriteLine(string.Join(" , ",notReadOnlyArray));
            // first update , second , third

            var readOnlyArray = Array.AsReadOnly(notReadOnlyArray);
            readOnlyArray[1] = "second update"; // エラー発生

            Console.ReadKey();
        }
```

Array.AsReadOnlyメソッドで配列を作るとそのあと編集しようとしてもエラーが発生する。


# BinarySearch

配列の中に検索したい値があるかの確認が出来る。
BinarySearchを実行する場合は配列をソートする必要がある。

該当結果がない場合は-1がかえって来る
該当するものがある場合はそのindexが返ってくる

検索ではindexOfも使える↓
https://docs.microsoft.com/ja-jp/dotnet/api/system.array.indexof?view=netframework-4.8

オバーロードに関してはこちら↓
https://docs.microsoft.com/ja-jp/dotnet/api/system.array.binarysearch?view=netframework-4.8

### 例

```c#
            string[] stringValues = new string[] { "ruby", "go", "c", "c#" };
            object seachValue = "c";

            Array.Sort(stringValues);

            Console.WriteLine(string.Join(" , ", stringValues));
            // c , c# , go , ruby

            var result = Array.BinarySearch(stringValues, seachValue);
            Console.WriteLine(result);
            // 0

            Console.ReadKey();
```


# Clear

配列の要素を削除したい場合に使う

すべて削除する場合ではなく部分で気に削除したい場合も使える。

消した部分はnullとして残る

配列を作りなおす場合はlistにしてnull部分を削除して配列を作りなおす？

### 例

```c#
        static void Main(string[] args)
        {
            string[] stringValues = new string[] { "first", "second", "want delete", "third" };
            Array.Clear(stringValues, 2, 1);

            Console.WriteLine(string.Join(" , ", stringValues));
            // first , second ,  , third

            List<string> stringList = new List<string>(stringValues);
            stringList.Remove(null);

            string[] newStringValues = stringList.ToArray();
            Console.WriteLine(string.Join(" , ", newStringValues));
            // first , second , third

            Console.ReadKey();
            
        }

```

# Clone

配列はたしか参照型？だからほかの変数に代入しても

元の配列を変更したらそれを参照している変数すべてに影響が出ちゃう

Cloneを行えばそれを回避できる。

cloneをする前に(string[]) としてどのような形でcloneするのか指定する必要がある

### 例

```c#
        static void Main(string[] args)
        {
            string[] stringValues = new string[] { "first", "second", "third" };
            string[] newStringValues = stringValues;
            stringValues[0] = "first update";
            Console.WriteLine(string.Join(" , ", newStringValues));
            // first update , second , third => stringValuesの変更が反映されてしまう

            string[] stringValuesBeforeClone = new string[] { "first", "second", "third" };
            string[] cloneStringValues = (string[]) stringValuesBeforeClone.Clone();

            stringValuesBeforeClone[0] = "first update";
            Console.WriteLine(string.Join(" , ", cloneStringValues));
            // first , second , third => stringValuesVeforeCloneの変更が反映されない


            Console.ReadKey();
            
        }

```

# ConstrainedCopy

配列からデータを持ってきて他の配列にデータをコピーする。
引数としては

(データを持ってくる配列,データを持ってくる配列の位置,コピーする対象の配列,コピーする配列の位置,コピーする長さ)

といった感じ

### 例

```c#
        static void Main(string[] args)
        {
            string[] baseArray = new string[] { "first", "second", "third" };
            string[] otherArray = new string[] { "other", "other", "other" };

            Array.ConstrainedCopy(baseArray, 0, otherArray, 2, 1);

            Console.WriteLine(string.Join(" , ", otherArray));
            // other , other , first

            Console.ReadKey();
            
        }

```


# ConvertAll

配列の中身をすべてメソッドを実行して変換する

### 例

配列の中身をstringからintに変換

```c#
        static void Main(string[] args)
        {
            string[] stringNumberArray = new string[] { "1", "2", "3" };
            int[] intNumberArray 
                = Array.ConvertAll<string, int>(stringNumberArray, delegate (string str) { return int.Parse(str); });

            Console.ReadKey();
            
        }
```



# Copy

配列のコピーを行う

いまいちConstrainedCopyとの違いがわからない...


### 例

```c#
        static void Main(string[] args)
        {
            string[] baseArray = new string[] { "first", "second", "third" };
            string[] otherArray = new string[] { "other", "other", "other" };

            Array.Copy(baseArray, 0, otherArray, 2, 1);

            Console.WriteLine(string.Join(" , ", otherArray));
            // other , other , first

            Console.ReadKey();

        }
```


# copy

配列の中身を他の配列にコピーします。

引数にコピー先とコピーの開始位置を設定します。

### 例

```c#
        static void Main(string[] args)
        {
            string[] sourceArray = new string[] { "first", "second", "third" };
            string[] targetArray = new string[] { "other", "other", "other", "other", null, null, null, null };

            sourceArray.CopyTo(targetArray, 4);

            Console.WriteLine(string.Join(" , ", targetArray));
            // other , other , other , other , first , second , third ,

            Console.ReadKey();

        }
```


# CreateInstance

配列の作成を行う

SetValueで値の設定
GetValueで値の取得が出来る。


### 例

```c#

        static void Main(string[] args)
        {
            string[] sourceArray = (string[]) Array.CreateInstance(typeof(String), 10);
            sourceArray.SetValue("go", 0);
            sourceArray.SetValue("ruby", 1);
            sourceArray.SetValue("c#", 2);

            Console.WriteLine(string.Join(" , ", sourceArray));
            // go , ruby , c# ,  ,  ,  ,  ,  ,  ,

            Console.ReadKey();

        }
```


# Empty

からの配列を返します。

### 例

```c#
        static void Main(string[] args)
        {
            string[] sourceArray = new string[] { "go", "ruby", "c#" };
            Console.WriteLine(string.Join(" , ", sourceArray));
            // go , ruby , c#
            sourceArray = Array.Empty<string>();

            Console.WriteLine(sourceArray.Count());
            // 0
            Console.WriteLine(string.Join(" , ", sourceArray));
            // 

            Console.ReadKey();

        }
```

# Exists

配列の中に特定の条件のもがあるか確認する。

### 例

```c#
        static void Main(string[] args)
        {
            string[] sourceArray = new string[] { "go", "ruby", "c#" };
            bool result = Array.Exists(sourceArray, element => element.StartsWith("c"));
            Console.WriteLine(result);
            // True

            Console.ReadKey();

        }
```


# Find

要素の中で条件に一致するものの中で一番インデックス番号が小さい値を返す。

インデックス番号を返すわけではない


### 例

```c#

        static void Main(string[] args)
        {
            int[] targetArray = new int[] { 1, 10, 100, 1000 };
            int result = Array.Find(targetArray, e => e >= 100);
            Console.WriteLine(result.ToString());
            // 100

            Console.ReadKey();

        }
```


# FindAll

要素の中で条件に一致するものすべてを取得する。

### 例

```c#
        static void Main(string[] args)
        {
            int[] targetArray = new int[] { 1, 10, 100, 1000 };
            int[] result = Array.FindAll(targetArray, e => e >= 100);
            Console.WriteLine(string.Join(" , ",result));
            // 100 , 1000

            Console.ReadKey();

        }
```



# FindIndex

要素の中で条件に一致する要素の一番小さいindexを返す

### 例

```c#
        static void Main(string[] args)
        {
            int[] targetArray = new int[] { 1, 10, 100, 1000 };
            int result = Array.FindIndex(targetArray, e => e >= 100);
            Console.WriteLine(result.ToString());
            // 2

            Console.ReadKey();

        }
```

# FindLast

要素の中で条件に一致する要素の中で一番index番号が大きい要素を返す。

indexを返すわけではない。

### 例

```c#

        static void Main(string[] args)
        {
            int[] targetArray = new int[] { 1, 10, 100, 1000, 10000 };
            int result = Array.FindLast(targetArray, e => e >= 100);
            Console.WriteLine(result.ToString());
            // 10000

            Console.ReadKey();

        }
```

# FindLastIndex

要素の中で条件に一致する要素の中で一番おおきいindexを返す。

### 例

```c#

        static void Main(string[] args)
        {
            int[] targetArray = new int[] { 1, 10, 100, 1000, 10000 };
            int result = Array.FindLastIndex(targetArray, e => e >= 100);
            Console.WriteLine(result.ToString());
            // 4

            Console.ReadKey();

        }
```


# foreach

配列のそれぞれの要素に対して処理を行う


### 例

```c#
        static void Main(string[] args)
        {
            int[] targetArray = new int[] { 1, 10, 100, 1000, 10000 };
            foreach (var i in targetArray)
            {
                Console.WriteLine(i.ToString());
            }
            // 1
            // 10
            // 100
            // 1000
            // 10000

            Console.ReadKey();

        }
```


# GetLength

多次元配列の場合に特定の次元の配列の数を返す

### 例

```c#
        static void Main(string[] args)
        {
            int[,] targetArray = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };
            int oneDimentionalCount = targetArray.GetLength(0);
            Console.WriteLine(oneDimentionalCount);
            // 2

            int twoDimentionalCount = targetArray.GetLength(1);
            Console.WriteLine(twoDimentionalCount);
            // 4

            Console.ReadKey();

        }
```


# GetLowerBound

いまいち使い方がわからないけど

指定した次元の最初のindexを取得する

### 例

```c#
        static void Main(string[] args)
        {
            int[] numberArray = new int[] { 0, 1, 2, 3, 4, 5 };
            int lowerBound = numberArray.GetLowerBound(0);
            Console.WriteLine(lowerBound);
            // 0

            Console.ReadKey();

        }
```


# GetUpperBound

指定した次元の最後のindexを取得する。

### 例

```c#

        static void Main(string[] args)
        {
            int[] numberArray = new int[] { 0, 1, 2, 3, 4, 5 };
            int upperBound = numberArray.GetUpperBound(0);
            Console.WriteLine(upperBound);
            // 5

            Console.ReadKey();

        }
```


# IndexOf

配列内の要素にて一致するものがあればその最初のindexを返す

### 例

```c#
        static void Main(string[] args)
        {
            string[] targetArray = new string[] { "A", "B", "C", "Z", "D", "Z" };
            int result = Array.IndexOf(targetArray, "Z");
            Console.WriteLine(result);
            // 3

            Console.ReadKey();

        }
```


# LastIndexOf

配列内の要素にて一致するものがあればその最後のindexを返す

### 例

```c#
        static void Main(string[] args)
        {
            string[] targetArray = new string[] { "A", "B", "C", "Z", "D", "Z" };
            int result = Array.LastIndexOf(targetArray, "Z");
            Console.WriteLine(result);
            // 5

            Console.ReadKey();

        }
```


# Resize 

配列の長さを変える

### 例

```c#
        static void Main(string[] args)
        {
            string[] sourceArray = new string[] { "go", "ruby", "c", "c++" };
            Console.WriteLine(sourceArray.Length);
            // 4

            Array.Resize(ref sourceArray, 6);

            Console.WriteLine(sourceArray.Length);
            // 6

            Console.WriteLine(string.Join(" , ", sourceArray));
            // go , ruby , c , c++ ,  ,

            Console.ReadKey();

        }
```

# Reverse

配列を反転

引数に配列のみを渡すと全体を反転させる

三つ引数を渡す場合は

(配列、反転の開始位置、反転を行う要素の数)

を設定して部分的に反転させられる。


### 例


```c#

        static void Main(string[] args)
        {
            int[] targetArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            Array.Reverse(targetArray, 4, 3);

            Console.WriteLine(string.Join(" , ", targetArray));
            // 1 , 2 , 3 , 4 , 7 , 6 , 5 , 8 , 9 , 10

            Array.Reverse(targetArray);

            Console.WriteLine(string.Join(" , ", targetArray));
            // 10 , 9 , 8 , 5 , 6 , 7 , 4 , 3 , 2 , 1

            Console.ReadKey();

        }
```


# Sort

配列をソートできる。

配列のみを渡すとそれっぽくソートしてくれる

独自にソートのルールを作ることが出来て、その場合は引数を三つ渡す。

比較する関数はICompareを継承して関数を作る。


### 例


独自のルールで配列をソートする場合

```c#

    public class stringLengthCompare : IComparer
    {
        // Call CaseInsensitiveComparer.Compare with the parameters reversed.
        public int Compare(Object x, Object y)
        {
            if (x.ToString().Length < y.ToString().Length)
            {
                return -1;
            }
            else if (x.ToString().Length > y.ToString().Length)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IComparer stringComparer = new stringLengthCompare();

            string[] targetArray = new string[] { "aaa", "aaaaaa", "aa", "aaaaaaaaa", "aaaaa" };

            Array.Sort(targetArray, 0, 5, stringComparer);

            Console.WriteLine(string.Join(" , ", targetArray));
            // aa , aaa , aaaaa , aaaaaa , aaaaaaaaa

            Console.ReadKey();

        }

    }
```

配列をそのままソートする場合

配列の中身が数字であれば小さい順にソートされる。

```c#

        static void Main(string[] args)
        {
            int[] targetArray = new int[] { 1, 4, 2, 5, 7, 6, 8, 0 };
            Array.Sort(targetArray);

            Console.WriteLine(string.Join(" , ", targetArray));
            // 0 , 1 , 2 , 4 , 5 , 6 , 7 , 8

            Console.ReadKey();

        }


```


# TrueForAll

配列ないのすべての要素が条件に一致するか調べる。

### 例

```c#
        static void Main(string[] args)
        {
            int[] targetArray = new int[] { 2, 4, 6, 8, 10, 12, 14 };
            bool result = Array.TrueForAll(targetArray, e => e % 2 == 0);
            Console.WriteLine(result);
            // True

            Console.ReadKey();

        }
```