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();
}
}
}
|
|
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();
}
}
}
|
|
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();
}
}
}
|
|
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();
}
}
}
|