C # Set -- Array

Source: Internet
Author: User
Tags array sort

The Array class is an implicit base class for all one-dimension and multi-dimensional arrays, and is also the most basic type for implementing standard set interfaces. The Array class provides a set of common methods for all arrays, regardless of the type of these Array elements.

Because arrays are so important, C # provides clear syntax for declaring arrays and initializing arrays. When using the C # syntax to declare an Array, CLR implicitly constructs an Array class-synthesize a pseudo type to match the dimension of the Array and the type of the Array element. In addition, this pseudo type implements the generic set interface, such as the IList <string> interface.

CLR performs special processing when creating an array-type instance-allocating continuous space for the array in memory. This makes the Index Array very efficient, but it prevents the modification or correction of the array size.

The Array class implements the IList <T> and IList interfaces. The Array class implements the IList <T> interface to ensure the integrity of the interface. However, when you call the Add or Remove method of the IList <T> interface on an array of a fixed length set such as an array, an exception is thrown (because the length of the array cannot be changed once the array instance is declared ). The Array class provides a static Resize method, which creates a new Array instance and copies the elements of the current Array to the new instance. In addition, when an array is referenced anywhere in a program, the original version of the array instance is executed. Therefore, if you want to adjust the collection size, you 'd better use the List <T> class.

The array element can be of the value or reference type. Value-type array elements exist directly in the array. For example, an array containing three integers occupies 24 bytes of continuous memory. The space occupied by an array element of the reference type is the same as that occupied by a reference (4 bytes in a 32-bit environment, and 64 bytes in an environment 8 bytes ). Let's take a look at the following code:

[] numbers = [] =1] = 7=  StringBuilder[] =  StringBuilder(] =  StringBuilder(] =  StringBuilder();

The corresponding memory allocation changes are shown in the following figure:

After int [] numbers = new int [3] is executed, 8 × 3 = 24 bytes are allocated in the memory, and each byte is 0.

After numbers [0] = 1 is executed, the first 8 bytes after the array declaration become 00 00 01.

Similarly, after numbers [1] = 7 is executed, the 8 bytes in the second segment become 00 00 07.

Corresponding to the array of reference type, we use a figure to describe the memory allocation:

It looks complicated. In fact, the memory allocation is as follows:

 

You can Clone an array by using the Clone method, for example, arrayB = arrayA. Clone (). However, the cloned array is copied in a shortest, that is, the part of the content contained in the array will be cloned. Simply put, if an array contains value-type objects, the values of these objects are cloned. If the child element of the array is of the reference type, only the address of the reference type is cloned.

StringBuilder[] builders2 == (StringBuilder[])builders.Clone();

Corresponding memory allocation:

If you want to perform a deep copy operation, that is, to clone sub-objects of the reference type, you need to traverse the array and manually clone each array element. Deep clone rules also apply to other. NET Collection types.

Although the array is designed with 32-bit indexes, it also supports 64-bit indexes to some extent, which requires methods that receive both Int32 and Int64 parameters. These overload methods do not actually make sense, because CLR does not allow any object, including an array, to be larger than 2 GB (whether a 32-bit system or a 64-bit system)

Construct arrays and index arrays

The simplest way to create arrays and index arrays is through the C # Language builder.

Int[] myArray={,, first=myArray[ last = myArray[myArray.Length-];

Alternatively, you can dynamically create an Array instance by calling the Array. CreateInstance method. You can specify the array element type and array dimension in this way. The GetValue and SetValue methods allow you to access the elements of the dynamically created array instance.

Array a = Arrat.CreateInstance((), a.SetValue(, s  = ()a.getValue([] cSharpArray = ( s2  = cSharpArray[];

The dynamically created zero-index array can be converted into a matching or Compatible C # array. For example, if Apple is a subclass of Fruit, Apple [] can be converted to Fruit []. This is why object [] is not a unified Array type, but an Array class. The answer is that object [] is not only incompatible with multi-dimensional arrays, but also incompatible with value-type arrays. Therefore, we use the Array class as the unified Array type.

GetValue and SetValue also apply to the arrays generated by the compiler. If you want to write a method to process arrays of any type and any dimension, these two methods are very useful. For multi-dimensional arrays, these two methods can treat an array as an index parameter.

  GetValue(   SetValue( value,  [] indices)

The following method prints the first element of any array on the screen, regardless of the array dimension.

+ [] indexers =   +[] oneD = { , , [,] twoD = { {,}, {,WriteFirstValue (twoD); }

When the SetValue method is used, if the element is not compatible with the array type, an exception is thrown.

No matter which method is used to instantiate an array, the array element is automatically initialized. For an array that references a type element, the initialization array element is to assign null values to these array elements. For an array element of the value type, the default value of the value type is assigned to the array element. In addition, you can call the Clear method of the Array class to complete the same function. The Clear method does not affect the array size. This is different from the common Clear method (such as the ICollection <T>. Clear method). The common Clear method clears all elements of the set.

 

Traverse Arrays

Using the foreach statement, you can easily traverse the array:

[] myArray = { , ,  ( val 

You can also use the Array. ForEach method to traverse the Array.

   ForEach<T> (T[] array, Action<T> action);

This method uses the Action proxy. The signature of this proxy method is (a parameter is received and no value is returned ):

   Action<T> (T obj);

The following code shows how to use the ForEach method.

Array.ForEach ([] { , ,  }, Console.WriteLine);

You may be curious about how Array. ForEach is executed.

   ForEach<T>(T[] array, Action<T>( array ==   ArgumentNullException(( action ==   ArgumentNullException(( i =  ; i < array.Length; i++

Execute the for loop internally and call the Action proxy. In the above example, we call the Console. WriteLine method, so we can output 1, 2, 3 on the screen.

 

Obtain the length and dimension of an array.

Array provides the following methods or attributes to obtain the length of an Array and its dimensions:

  GetLength (  GetLongLength (  Length {   LongLength {   GetLowerBound (  GetUpperBound (  Rank { ; }
GetLength and GetLongLength return the Length of the specified dimension (0 indicates a one-dimensional array), Length and LongLength return the total number of all elements in the array (including all dimensions ).

GetLowerBound and GetUpperBound are very useful for multi-dimensional arrays. The result returned by GetUpperBound is equal to the GetLowerBound + GetLength of the specified dimension.

 

Search for Arrays

The Array class provides a series of external methods to search for elements in a dimension. For example:

  • BinarySearch: quickly finds the specified element in a sorted array;
  • IndexOf/LastIndex method: searches for a specified element in an unordered array;
  • Find/FindLast/FindIndex/FindLastIndex/FindAll/Exists/TrueForAll method: search for one or more elements in an unordered Array Based on the specified Predicated <T> (proxy.

If the specified value is not found, these search methods in the array will not throw an exception. On the contrary, the search method returns-1 (assuming that the index of the array starts with 0), or the default value of the generic type is returned (int returns 0, string returns null ).

Binary Search is fast, but it only appliesAfter sortingAnd the elements of the array are sorted by size, rather than by equality. Because of this, the binary search method can receive IComparer or IComparer <T> objects to sort the elements. The passed IComparer or IComparer <T> object must be consistent with the sorting comparator used by the current array. If the comparator parameter is not provided, the array uses the default sorting algorithm.

The IndexOf and LastIndexOf Methods traverse the array and return the position of the first (or last) element based on the specified value.

The predicate-based search method accepts a method proxy or lamdba expression to determine whether the element meets "match ". A predicate is a simple proxy that receives an object and returns the bool value:

   Precicate<T>(T );

In the following example, we search for characters in the character array that contain letters:

  Main([] names = { , ,  match =  ContainsA( name.Contains(

The above code can be simplified:

  Main([] names = { , ,  match = Array.Find(names, ( name) {  name.Contains(

If the lambda expression is used, the code can be simpler:

  Main([] names = { , ,  match = Array.Find(names, name=>name.Contains(

The FindAll method returns all elements that meet the predicate from the array. In fact, this method is equivalent to the Enumerable. Where method, except that the FindAll of the array returns matching elements from the array, and the Where method returns from IEnumerable <T>.

If the array member meets the specified predicate, The Exists method returns True, which is equivalent to the Enumerable. Any method.

Therefore, if All the members of the array meet the specified predicate, The TrueForAll method returns True, which is equivalent to the Enumerable. All method.

 

Sort Arrays

Arrays have the following built-in sorting methods:

   Sort<T>       Sort(Array keys[], Array items);

The methods above all have the version of the overload, and the overload method accepts the following parameters:

  • Int index, which is sorted from the specified index position.
  • Int length, the number of elements to be sorted starting from the specified index position
  • ICompare <T> comparer, an object used for sorting decisions
  • Comparison <T> comparison, used as a proxy for sorting decisions

The following code demonstrates how to implement a simple sorting:

  Main([] numbers = { ,, ( number 

The Sort method can also receive two parameters of the array type, and then Sort the elements of each Array Based on the sorting result of the first array. In the following example, The number array and character array are sorted by the number array order.

  Main([] numbers = { ,,[] names = { , ,  ( number      ( name 

The Array. Sort method requires the Array to implement the IComparer interface. This means that most types of C # can be sorted. If the array elements cannot be compared, or you want to reload the default sorting, you need to provide custom Comparison when calling the Sort method. Therefore, the custom sorting algorithm can be implemented in the following two ways:

1) Use a help object to implement the IComparer or IComparer <T> Interface

     Sort<T>(T[] array, System.Collections.Generic.IComparer<T> comparer)

2) use the Comparison Interface

   Sort<T>(T[] array, Comparison<T> comparison)

The Comparison agent follows the IComparer <T>. CompareTo Syntax:

   Comparison<T> (T x, T y);
If the position of x is before y,-1 is returned. If x is after y, 1 is returned. If the position is the same, 0 is returned.

Let's take a look at the source code of the Array Sort <T> (T [] array, Comparison <T> comparison) method:

   Sort<T>(T[] array, Comparison<T><T> comparer =  FunctorComparer<T>

Therefore, Comparison <T> can be converted to IComparer <T> internally. Therefore, the first method is recommended if you need to consider performance when implementing custom sorting. In addition, we analyze the source code of Sort <T> (T [] array, System. Collections. Generic. IComparer <T> comparer,

   Sort<T>(T[] array,  index,  length, System.Collections.Generic.IComparer<T> (length >  (comparer ==  || comparer == Comparer<T> (TrySZSort(array, , index, index + length - <T>

We can see that we first try to call the Sort method of the unmanaged code. If the sorting is successful, we will return it directly. Otherwise, you can call the Sort method of the unmanaged code (C # ArraySortHelper) for sorting:

  Sort(T[] keys,  index,  length, IComparer<T>     (comparer == = Comparer<T>+ index -   InvalidOperationException(Environment.GetResourceString(

If you are interested, you can continue to analyze the IntrospectiveSort method and DepthLimitedQuickSort. However, MSDN has provided a summary,

Consciousness means there are three sorting algorithms:

  • If the partition size is smaller than 16, use the insert sorting algorithm.
  • If the partition size exceeds 2 * LogN, and N is the range of the array, use heap sorting.
  • In other cases, use the quick release

 

Returns an array element.

You can use the following method to reverse all or some elements of the array.

     Reverse (Array array,  index,  length);

If you care about performance, do not directly call the Array Reverse method, but create a custom RerverseComparer. For example, in the following example, the performance gap between calling Array. Reverse and CustomReverse on my computer is about 20%.

  Main( seeds = = =  ( i = ; i < seeds; i++=  Staff { StaffNo = r.Next( == + (t2 - t1).Milliseconds +  == + (t2 - t1).Milliseconds +    StaffNo { ;   Name { ;   CompareTo(= obj    StaffComparer : IComparer<Staff> 

Execution result:

 

Copy an array

Array provides four methods to implement shortest Copy: Clone, CopyTo, Copy, and ConstrainedCopy. The first two methods are instance methods, and the last two are static methods.

The Clone method returns a new (Shortest copy) array. The CopyTo and Copy methods Copy the continuous subsets of arrays. To copy a multi-dimensional rectangular array, You need to map your multi-dimensional Index to a linear index. For example, if a position array of 3x3 is used, the linear index corresponding to postion [] is 1x3 + 1 = 4. The range of the original array and the target array can be exchanged without any problems.

ConstrainedCopy performs atomic operations. If not all required elements are successfully copied, the operation is rolled back.

Array also provides the AsReadOnly method, which returns a package to prevent the value of the Array element from being changed.

Finally, the Clone method is implemented by external unmanaged code.

  Object MemberwiseClone()

Likewise, Copy, CopyTo, and ConstraintedCopy call external implementations.

    Copy(Array sourceArray,  sourceIndex, Array destinationArray,  destinationIndex,  length,  reliable);

 

Convert an array and reduce its size

Array. ConvertAll is created and a new Array of TOutput type is returned. The Converter proxy is called to copy elements to the new Array. Converter is defined as follows:

  TOutput Converter<TInput,TOutput>(TInput input)

The following code converts a floating point array to an int array.

[] reals = { , , [] wholes = Array.ConvertAll(reals, f => ( a 
The Resize method creates a new array, copies the elements to the new array, and returns the new array. The original array does not change.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.