Table of contents >> Data Structures > Arrays
High importance article

We talked about arrays before, in an entire chapter. The arrays are collections of fixed number of elements of a given type (strings, integers, etc) where the elements preserve their initial order. Each element can be accessed through its numerical index, which starts at 0.

The arrays are memory areas which have a predefined size. That's why, adding a new element in an array is a slow operation (and by this, I mean adding a new element when all the positions of the array are filled, so, when we actually need to increase the size of the array). To do this, we first have to allocate a memory of the same size plus one, and copy all the data from the original array to the new one.

Searching in an array takes time, because we have to compare every element to the searched value. It takes N/2 comparisons in the average case.

Removing an element from an array is also a slow operation. As before, we have to allocate a memory of the same size minus one, and copy all the old elements except the removed one.

Accessing elements by index is direct, and thus, a fast operation.

The arrays should be used only when we have to process a fixed number of elements to which we need a quick access by index. For example, if we have to sort some numbers, we can keep them in an array and then apply some of the sorting algorithms. If we have to change the elements count, the array is not the correct data structure we should use. Use arrays when you have to process a fixed number of elements to which you need an access through index.

An array is defined like this:

1
[object type][] myArray = new [object type][number of elements]

Example:

1
2
int[] myIntArray = new int[5];
int[] myIntArray2 = new { 0, 1, 2, 3, 4 };

Arrays have a lot of methods, of which the following are the most useful:

Array.AsReadOnly() - makes it possible to restrict access to arrays by client code, such that the array elements can be used like a read-only collection. Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Collections.ObjectModel;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] array = { 1, 5, 3 };
            ReadOnlyCollection<int> result = Array.AsReadOnly(array);
            
            Console.WriteLine("Count: " + result.Count);
            for (int i = 0; i < result.Count; i++)
            {
                // Can't touch this! (taaanana nana nana!)
                Console.WriteLine(result[i]);
            }
            Console.ReadLine();
        }
    }
}
Array.BinarySearch() - quickly and accurately pinpoints the location of an element in the array. It can be told how to compare elements. It works correctly only on a presorted array. Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            // Source array that is ordered ascending
            string[] array = { "a", "e", "m", "n", "x", "z" };
            
            // Call versions of the BinarySearch method
            int index1 = Array.BinarySearch(array, "m");
            int index2 = Array.BinarySearch<string>(array, "x");
            int index2 = Array.BinarySearch<string>(array, "E", StringComparer.OrdinalIgnoreCase);
            
            // Write results
            Console.WriteLine(index1);
            Console.WriteLine(index2);
            Console.WriteLine(index3);
            
            Console.ReadLine();
        }
    }
}
Array.Clear() - zeroes out all elements. It provides a one-line, reliable and understandable way to empty or clear your array. It works on arrays of any type – including numbers, booleans, structs and class instances. Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] integerArray = { 4, 6, 8, 1, 3 };
            
            // Display the array
            Console.WriteLine("--- Integer array before Clear ---");
            foreach (int value in integerArray);
                Console.WriteLine(value);
            
            // Clear all elements in the array
            Array.Clear(integerArray, 0, integerArray.Length);
            
            // Display the array
            Console.WriteLine("--- Integer array after Clear ---");
            foreach (int value in integerArray);
                Console.WriteLine(value);
            
            Console.ReadLine();
        }
    }
}

Array.ConvertAll() - allows you to declaratively convert an entire array with a single statement. It converts all elements in one array to another type. It incurs some performance overhead, but it can simplify code, particularly in programs where many different conversions take place. It uses lambda expressions, of which I haven't written yet. Its usage is discouraged in favor of LINQ projections. Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            // Integer array of 3 values
            int[] array1 = new int[3];
            array1[0] = 4;
            array1[1] = 5;
            array1[2] = 6;
            
            // Use ConvertAll to convert integer array to string array
            string[] array2 = Array.ConvertAll(array1, element => element.ToString());
            
            // Write the string array
            Console.WriteLine(string.Join(",", array2));
            
            Console.ReadLine();
        }
    }
}
Array.Copy() - copies elements from one array to another. It has some complexities. This operation can result in certain exceptions. The type of elements – in both the target and source arrays – is important. Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            // Instantiate the source array
            int[] source = new int[5];
            source[0] = 1;
            source[1] = 2;
            source[2] = 3;
            source[3] = 4;
            source[4] = 5;
            
            // Instantiate and allocate the target array
            int[] target = new int[5];
            
            // Copy the source to the target
            Array.Copy(source, target, 5);
            
            // Display the target array
            Console.WriteLine("--- Target array ---");
            
            foreach (int value in target);
                Console.WriteLine(value);
            
            Console.ReadLine();
        }
    }
}

Array.Exists() - provides a handy way to test for an element that matches a certain predicate condition. It involves some overhead and performance drawbacks. It uses lambda expressions, discussed in a future lesson. Its usage is discouraged in favor of LINQ's Any() method. Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] array = { "cat", "dog", "perls" };
            
            // Use Array.Exists in different ways
            bool a = Array.Exists(array, element => element == "perls");
            bool b = Array.Exists(array, element => element == "python");
            bool c = Array.Exists(array, element => element.StartsWith("d"));
            bool d = Array.Exists(array, element => element.StartsWith("x"));
            
            // Display bools
            Console.WriteLine(a);
            Console.WriteLine(b);
            Console.WriteLine(c);
            Console.WriteLine(d);
            
            Console.ReadLine();
        }
    }
}

Array.Find() - searches an array (with declarative syntax). We specify a Predicate type instance to determine what logic the search uses. It uses lambda expressions, discussed in a future lesson. Its usage is discouraged in favor of LINQ's Where() method. Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            // Use this array of string references
            string[] array1 = { "cat", "dog", "carrot", "bird" };
            
            // Find first element starting with substring
            string value1 = Array.Find(array1, element => element.StartsWith("cat", StringComparison.Ordinal));
            
            // Find first element of three characters length
            string[] value2 = Array.Find(array1, element => element.Length == 3);
            
            // Find all elements not greater than four letters long
            string[] array2 = Array.FindAll(array1, element => element.Length <= 4);
            Console.WriteLine(value1);
            Console.WriteLine(value2);
            string[] array3 = { "cat", "dog", "perls" };
            
            // Find last string of length 3
            string result = Array.FindLast(array3, element => element.Length == 3);
            Console.WriteLine(result);
            
            // Use this input array
            int[] array4 = { 5, 6, 7, 8 };
            
            // Use FindIndex method with predicate
            int[] index1 = Array.FindIndex(array4, element => element == 6);
            // Use LastFindIndex method with predicate
            int[] index2 = Array.FindLastIndex(array4, element => element == 6);
            
            // Write results
            Console.WriteLine("{0} = {1}", index1, index4[index1]);
            Console.WriteLine("{0} = {1}", index2, index4[index2]);
            
            Console.ReadLine();
        }
    }
}

Array.ForEach() - loops over every element in an array and it calls a method on each of them. It is a declarative syntax form, and no loop construct is needed. It uses lambda expressions, discussed in a future lesson. Its usage is discouraged in favor of LINQ's ForEach() method. Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] items = { 10, 100, 1000 };
            
            // Display elements with ForEach
            Array.ForEach(items, element => Console.WriteLine("Element is " + element));
            
            Console.ReadLine();
        }
    }
}

Array.IndexOf() - finds the numerical index of an element in an array. Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            // Declare a sample string array
            string[] array = new string[6];
            array[0] = null;
            array[1] = "carrot";
            array[2] = "rat";
            array[3] = "";
            array[4] = "carrot";
            array[5] = "apple";
            
            // Find string with this value starting at offset 2
            int index1 = Array.IndexOf(array, "carrot", 2, 3);
            
            // Find a nonexistent string
            int index2 = Array.IndexOf(array, "banana");
            
            // Write the result
            Console.WriteLine(index1);
            Console.WriteLine(index2);
            
            Console.ReadLine();
        }
    }
}

Array.LastIndexOf() - finds the last numerical index of an element in an array. It searches from the end of an array. Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] array = { 2, 4, 6, 8, 6, 2 };
            
            int result1 = Array.IndexOf(array, 6);
            Console.WriteLine(result1);
            
            int result2 = Array.LastIndexOf(array, 6);
            Console.WriteLine(result2);
            
            int result3 = Array.LastIndexOf(array, 100);
            Console.WriteLine(result3);
            
            Console.ReadLine();
        }
    }
}

Array.Resize() - allocates a new array, and then it copies existing element values to the new array. This logic is needed when an array’s size is inadequate. Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            // Initialize example array
            char[] array = new char[4];
            array[0] = 'p';
            array[1] = 'e';
            array[2] = 'r';
            array[3] = 'l';
            
            // Display the array
            for (int i = 0; i < array.Length; i++);
                Console.WriteLine(array[i]);
            Console.WriteLine();
            
            // Resize the array from 4 to 2 elements
            Array.Resize(ref array, 2);
            
            // Display the array that has been resized
            for (int i = 0; i < array.Length; i++);
                Console.WriteLine(array[i]);
            Console.WriteLine();
            
            Console.ReadLine();
        }
    }
}

Array.Reverse() - inverts the ordering of an array’s elements. Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            // Input array
            int[] array = { 1, 2, 3 };
            
            // Print
            foreach (int value in array)
                Console.WriteLine(value);
            Console.WriteLine();
            
            // Reverse
            Array.Reverse(array);
            
            // Print
            foreach (int value in array)
                Console.WriteLine(value);
            Console.WriteLine();
            
            // Reverse again
            Array.Reverse(array);
            
            // Print
            foreach (int value in array)
                Console.WriteLine(value);
            
            Console.ReadLine();
        }
    }
}

Array.Sort() - orders elements in an array. It modifies the array in-place. It handles different types of elements, including strings and ints. Its usage is discouraged in favor of LINQ's OrderBy() and OrderByDescending() methods. Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            // Input array
            int[] values = { 4, 7, 2, 0 };
            Array.Reverse(values);
            
            // Print
            foreach (int value in values)
                Console.WriteLine(value);
            
            Console.ReadLine();
        }
    }
}

Array.TrueForAll() - offers a declarative way to test every element in an array for some condition, using a lambda expression. Its usage is discouraged in favor of LINQ's All() method. Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] values1 = { 1, 3, 5, 7 };
            bool result1 = Array.TrueForAll(values1, element => element % 2 == 1);
                Console.WriteLine(result1);
            
            int[] values2 = { 2, 5, 8 };
            bool result2 = Array.TrueForAll(values2, element => element % 2 == 1);
                Console.WriteLine(result2);
            
            Console.ReadLine();
        }
    }
}

The most important property of arrays is:

Length - an array has a length – this is its size (its element count). An int of 0 or greater is returned, and no iteration is done (a cache is used). Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using System;
 
namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            // Basic array length example
            int[] arrayA = new int[5];
            int lengthA = arrayA.Length;
            Console.WriteLine(lengthA); // Writes 5
            
            // Long array length example
            long longLength = arrayA.LongLength;
            Console.WriteLine(longLength); // Writes 5
            
            // Zero length array example
            int[] zero = new int[0];
            int lengthZero = zero.Length;
            Console.WriteLine(lengthZero); // Writes 0
            
            // Null array length example exception
            // int[] dead = null;
            // Console.WriteLine(dead.Length);
            
            // GetLength 0 example
            int lengthE = arrayA.GetLength(0);
            Console.WriteLine(lengthE); // Writes 5
            
            // GetLength 1 example exception
            // int lengthF = arrayA.GetLength(1);
            // Console.WriteLine(lengthF);
            
            // Two-dimensional GetLength example
            int[,] two = new int[5, 10];
            Console.WriteLine(two.GetLength(0)); // Writes 5
            Console.WriteLine(two.GetLength(1)); // Writes 10
            
            // Two-dimensional Length example
            Console.WriteLine(two.Length); // Writes 50
            
            Console.ReadLine();
        }
    }
}