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;
}
- 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));
}
- 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; }
}
CodePudding user response:
Well IndexOf
is a correct implementation, which can be make to more general:
public static int IndexOf<T>(IEnumerable<T> source, Predicate<T> predicate)
{
if (source 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);
}
Edit: if you can't change Product
class, you have to change predicate
and explain there how to compare for equality:
int index = Utilities
.IndexOf(products, product => productToFind.Name == product.Name &&
productToFind.Price == product.Price);
Please, fiddle youself.