Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

IndexOf and Predicate


  public static int IndexOf(Product[] products, Predicate<Product> predicate)
      {
          if (products == null)
          {
              throw new ArgumentNullException();
          }
  
          for (int i = 0; i <= products.Length - 1;  i++)
          {
              if (predicate == null)
              {
                  throw new ArgumentNullException();
              }
              Product product = products[i];
              if (predicate(product))
              {
                  return i;
              }
          }
          return -1;
      }

  1. Searches for the index of a product in an products based on a predicate
    products Products used for searching
    predicate Product predicate
    If match found then returns index of product in products
    otherwise -1
    I am asked to make changes only in the IndexOf(Product[] products, Predict predict) method without touching the Product model.

   [Test]
           public void IndexOf_Products_ReturnsTwo()
           {
               var products = new Product[]
               {
                   new Product("Product 1", 10.0d),
                   new Product("Product 2", 20.0d),
                   new Product("Product 3", 30.0d),
               };
               var productToFind = new Product("Product 3", 30.0d);
   
               int index = Utilities.IndexOf(products, product => product.Equals(productToFind));
   
               Assert.That(index, Is.EqualTo(2));
           }

  1. Expected: 2 But was:-1

    public class Product
   {
       public Product(string name, double price)
       {
           Name = name;
           Price = price;
       }
   
       public string Name { get; set; }
   
       public double Price { get; set; }
   
   }

>Solution :

Well IndexOf is a correct implementation, which can be make to more general:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  public static int IndexOf<T>(IEnumerable<T> source, Predicate<T> predicate)
  {
      if (products is null)
      {
          throw new ArgumentNullException(nameof(source));
      }

      if (predicate == null)
      {
          throw new ArgumentNullException(nameof(predicate));
      }
    
      int index = 0;
      
      foreach (T item in source) {
          if (predicate(item))
              return index;

          index += 1;   
      } 

      return -1;
  }

The actual problem seems to be with Product class which doesn’t override Equals and GetHashCode methods.
Without Equals and GetHashCode .net compare references (which are different), not values.

To compare by values you should explain .net how to do it, something like this:

// Let Product be equatable with Product - IEquatable<Product>
public class Product : IEquatable<Product> {
  ...

  // Let .net know how to compare for equality:
  //TODO: put the right names for Name and Price
  public bool Equals(Product other) => other != null &&
    other.Name == Name &&
    other.Price == Price;

  public override bool Equals(object o) => o is Product other && Equals(other);

  public override int GetHashCode() => HashCode.Combine(Name, Price);
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading