0
\$\begingroup\$

To determine whether the specified array contains specific element or not, Array.Exists can be used if the given array is one dimensional. I am attempting to implement Exists method for multidimensional array cases.

The experimental implementation

static class MDArrayHelpers
{
 public static bool Exists<T>(Array array, Predicate<T> match)
 where T : unmanaged
 {
 if (ReferenceEquals(array, null))
 {
 throw new ArgumentNullException(nameof(array));
 }
 Type elementType = array.GetType().GetElementType();
 if (!elementType.Equals(typeof(T)))
 {
 throw new System.InvalidOperationException();
 }
 foreach (var element in array)
 {
 if (match((T)element))
 {
 return true;
 }
 }
 return false;
 }
}

Test cases

Predicate<int> isOne = delegate (int number) { return number == 1; };
Predicate<int> isFour = delegate (int number) { return number == 4; };
Console.WriteLine("One dimensional case");
int[] array1 = new int[] { 1, 2, 3 };
Console.WriteLine($"Is one existed in {nameof(array1)}: {Array.Exists(array1, isOne)}");
Console.WriteLine($"Is four existed in {nameof(array1)}: {Array.Exists(array1, isFour)}");
Console.WriteLine("");
Console.WriteLine("Two dimensional case");
int[,] array2 = { { 0, 1 }, { 2, 3 } };
Console.WriteLine($"Is one existed in {nameof(array2)}: {MDArrayHelpers.Exists(array2, isOne)}");
Console.WriteLine($"Is four existed in {nameof(array2)}: {MDArrayHelpers.Exists(array2, isFour)}");
Console.WriteLine("");
Console.WriteLine("Three dimensional case");
int[,,] array3 = { { { 0, 1 }, { 2, 3 } }, { { 0, 1 }, { 2, 3 } } };
Console.WriteLine($"Is one existed in {nameof(array3)}: {MDArrayHelpers.Exists(array3, isOne)}");
Console.WriteLine($"Is four existed in {nameof(array3)}: {MDArrayHelpers.Exists(array3, isFour)}");
Console.WriteLine("");
Console.WriteLine("Four dimensional case");
int[,,,] array4 = { { { { 0, 1 }, { 2, 3 } }, { { 0, 1 }, { 2, 3 } } }, { { { 0, 1 }, { 2, 3 } }, { { 0, 1 }, { 2, 3 } } } };
Console.WriteLine($"Is one existed in {nameof(array4)}: {MDArrayHelpers.Exists(array4, isOne)}");
Console.WriteLine($"Is four existed in {nameof(array4)}: {MDArrayHelpers.Exists(array4, isFour)}");

The output of the test code above:

One dimensional case
Is one existed in array1: True
Is four existed in array1: False
Two dimensional case
Is one existed in array2: True
Is four existed in array2: False
Three dimensional case
Is one existed in array3: True
Is four existed in array3: False
Four dimensional case
Is one existed in array4: True
Is four existed in array4: False

If there is any possible improvement, please let me know.

asked Mar 18, 2021 at 20:41
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

You can simply use the LINQ Enumerable.Any extension Method.

bool result = array4.Cast<int>().Any(x => x == 1);

This works for any collection implementing IEnumerable<T> and also for enumerations created algorithmically by C# Iterators.

According the the C# Programming Guide (Arrays):

Array types are reference types derived from the abstract base type Array. Since this type implements IEnumerable and IEnumerable<T>, you can use foreach iteration on all arrays in C#.

This statement is, however, misleading, since we need to cast the array here. Obviously, we only have the access to the non-generic interface IEnumerable.

LINQ Extension methods found in the Enumerable Class apply to IEnumerable<T> or IEnumerable.

answered Mar 18, 2021 at 21:07
\$\endgroup\$
4
  • \$\begingroup\$ Thank you for answering. I found that error CS1061: 'int[*,*,*,*]' does not contain a definition for 'Any' and no accessible extension method 'Any' accepting a first argument of type 'int[*,*,*,*]' could be found occurred in array4.Any(x => x == 1), but array4.Cast<int>().ToList().Any(x => x == 1) can be used as a solution. \$\endgroup\$ Commented Mar 19, 2021 at 1:01
  • 1
    \$\begingroup\$ The ToList() should not be needed \$\endgroup\$ Commented Mar 19, 2021 at 11:07
  • 1
    \$\begingroup\$ Please, see also my follow up question: Is the C# Programming Guide right on pretending that arrays implement IEnumerable<T>?. \$\endgroup\$ Commented Mar 19, 2021 at 15:06
  • 1
    \$\begingroup\$ @JimmyHu to use the Any LINQ extension method, you must import the corresponding namespace with using System.Linq; \$\endgroup\$ Commented Dec 13, 2021 at 15:12

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.