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.

\$\endgroup\$
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.

\$\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\$
    – JimmyHu
    Mar 19 '21 at 1:01
  • 1
    \$\begingroup\$ The ToList() should not be needed \$\endgroup\$
    – aloisdg
    Mar 19 '21 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\$ Mar 19 '21 at 15:06
  • 1
    \$\begingroup\$ @JimmyHu to use the Any LINQ extension method, you must import the corresponding namespace with using System.Linq; \$\endgroup\$ Dec 13 '21 at 15:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.