简体   繁体   中英

How can I use IndexOf in a List<object[]>?

If I declare a List like,

List<object[]> People = new List<object[]>();

(in which object[] has two elements)

People.Add(new object[] {"Sam", 18});

Is there a way I can find the index of a person like this?

People.IndexOf(new object[] {"Sam", 18});

I've tried doing it like it is above, but it returns -1 .


Solved this in my own crappy way by creating an extension method which takes a string parameter and loops through the list until it matches with one, then returns that index.

public static int OIndexOf(this List<object[]> List, string Check)
{
    for (int I = 0; I < List.Count; I++)
    {
        if ((string)List[I][0] == Check)
            return I;
    }
    return -1;
}

Generally speaking, you're going to need a concrete type to make this work, like a Person object or an int value.

The reason this is the case is because your type must implement an .Equals() method. It won't work with object objects, because the.Equals method for object compares references, not values, and your comparison will always return false unless you have the original object (not the case in your code, where you're creating a new object for comparison.

From the documentation for the IndexOf method :

This method searches all the elements of a one-dimensional array for value. To determine whether value exists in array, the method performs an equality comparison by calling each element's Equals method until it finds a match. This means that if the element overrides the Object.Equals(Object) method, that override is called.

Therefore, you need a Person object with an Equals() override. To wit:

public class Person
{
    public string Name { get; set; }

    public override bool Equals(Person other)
    {
        return Name.Equals(other.Name);
    }
}

If you want to compare an array of people, you need another type that encapsulates your Person array, and an Equals() method to check equality of every person in the array with every person in the other array.

If you had a reference to the actual array you wanted to look for then IndexOf would work in the way you want. But you are creating a new array, so it won't work.

The simplest way to do what you want is to use FindIndex :

People.FindIndex(p => p[0] == "Sam" && p[1] == 18)

To compare to the whole of an array in a variable at the same indices, use LINQ's SequenceEqual

var arr = new object[] {"Sam", 18};
People.FindIndex(p => arr.SequenceEqual(p));

If you really want to do it, you have to do it yourself.

Example: Create a new function:

int NewIndexOf(people, item)
{
    int index = 0;
    if(people.length) < 2
        return -1;

    foreach(var p in people)
    {
        p[0].Equals("Sam") && p[1].Equals(18)
        return index;
        ++index;
    }
    return -1;
}

Well, IndexOf uses the default equality comparer for a given type - Object , which is in your case comparers references . You have two new - two different referencies, which in turn means that both instances are considered unequal. To solve the problem you can:

Implement your own class:

 public class Person : IEquatable<Person> {
   public Person(string name, int age) {
     if (null == name)
       throw new ArgumentNullException(nameof(name));
     if (age < 0)
       throw new ArgumentOutOfRangeException(nameof(age));

     Name = name;
     Age = age;
   }

   public String Name {get;}

   public int Age {get;}

   public bool Equals(Person other) =>
     other != null && other.Name == Name && other.Age == Age;

   public override bool Equals(Object o) => Equals(o as Person);

   public override int GetHashCode() => Name.GetHashCode() ^ Age;
 }

Then you can put

 List<Person> People = new List<Person>();

 People.Add(new Person("Sam", 18));

 // Now .NET knows how to compare Person instances
 int index = People.IndexOf(new Person("Sam", 18));

Another approach (not a good practice, though) is to find index manually, with a help of LINQ :

 List<object[]> People = new List<object[]>();

 ...

 var index = People
    .Select((v, i) => new { v, i })
    .FirstOrDefault(pair => pair.v.SequenceEqual(new object[] { "Sam", 18 }))
   ?.i ?? -1;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM