Ole Albers
Ole Albers

Reputation: 9285

Check if array of ANY type contains element

I have two parameters I receive using reflection that could be of different types.

object array;
object value;

...

array=new int[] { 1,2,3};
value=3;

...

array=new string[] { "one","two","three"};
value="two";

I want to find out if value is inside array, no matter which type. The following command does not compile:

bool isInside=Array.Exists(array, q=>q==value);

The type arguments for method 'Array.Exists(T[], Predicate)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

How can I achieve my goal?

Upvotes: 2

Views: 1149

Answers (4)

Bartłomiej Popielarz
Bartłomiej Popielarz

Reputation: 344

Obligatory answer using LINQ:

//using System.Linq;
//using System.Reflection;
public static bool IsInArrayUnkownType(object array, object obj)
{
    Type type = array.GetType().GetElementType();
    MethodInfo contains = typeof(System.Linq.Enumerable).GetMethods().Where(m => m.Name == "Contains").First();
    MethodInfo containsUnGenericated = contains.MakeGenericMethod(new[] { type });
    object result = containsUnGenericated.Invoke(null, new object[] { array, obj });
    return (bool)result;
}

EDIT: Looking ot other solutions, I wouldn't really recommand this one, as reflection is slow and others did it far more elegantly.

Upvotes: 0

Colonel Software
Colonel Software

Reputation: 1440

Please try this one

var dynamicArray = (object[])array;
bool isInside = dynamicArray.Contains(value);

Upvotes: -1

Ivan  Chepikov
Ivan Chepikov

Reputation: 825

OS it is still an Array. So lets start with defining the variables as

Array array;
object value;

Array is IEnumerable we can define an extension class:

public static class EnumerableExtensions
{
    public static bool HasItem(this IEnumerable enumerable, object value)
    {
        return enumerable.OfType<Object>().Any(e => e.Equals(value));
    }
}

and use it like this:

 Array array = new[] { 1, 2, 3 };
 object value = 1;

 //false because the value is a string.
 var result = array.HasItem("1");

if you need it to be true some convertion logic should be added to HasItem method

Upvotes: 1

Sweeper
Sweeper

Reputation: 270860

One way I can think of is to cast the array to Array, then use a for loop to search through it:

var castedArray = (Array)array;
for (int i = 0 ; i < castedArray.Length ; i++) {
    if (castedArray.GetValue(i).Equals(value)) {
        Console.WriteLine("It exists!");
        break;
    }
}

Note that == won't work here because ints will be boxed.

If your arrays only have one dimension, Array.IndexOf would work as well (with castedArray and value), but if you want to handle 2D or 3D arrays as well, you need to check the Rank and use nested for loops.

Upvotes: 3

Related Questions