Say I have elements (X, Y, and Z) in a list, I have a function, that generates a percentage, of how much two objects resemble each other.
What I want to do, is run X against Y and Z using my compareElements, so:
compareElements(X,Y); // equals 55
compareElements(X,Z); // equals 60
Then Y against X and Z
compareElements(Y,X); // equals 55
compareElements(Y,Z); // equals 62
Then Z against Y and X
compareElements(Z,X); // equals 60
compareElements(Z,Y); // equals 62
Then, I return the highest value, which is 62.
Obviously, there's some repetition there, I don't need the repetition, but I'm not sure how to eliminate it.
How do I structure my LINQ query, or a function/algorithm to do this comparison on every element, without the repetition?
I'd prefer to use LINQ if I can, as I'm being passed an enumerable and the function returns before the list is actually enumerated, so we can save the cost of performing the compare, until the list is enumerated.
All I need is that highest value, of the compare functions, 62.
Note: My actual result set I'm working with averages between 3 and 10 elements in the list, that need to be ran through this compare function.
I'd be inclined to do it like this:
int count = list.Count;
var query = from index1 in Enumerable.Range(0, count)
from index2 in Enumerable.Range(index1 + 1, count - (index1 + 1))
select ComputeSimilarity(list[index1], list[index2]);
var maxSimilarity = query.Max();
I'm not sure I'm understanding you correctly, but try something like this:
public int compareElementList(List<Element> elements)
{
int result = 0;
for (int i = 0; i < elements.Count - 1; i++)
{
for (int q = i + 1; q < elements.Count; q++)
{
result = Math.Max(result, compareElements(elements[i], elements[q]));
}
}
return result;
}
This will eliminate the duplicate comparisons for you. It doesn't use LINQ, but I think it's still pretty readable.
UPDATE: Here is my version modified to handle IEnumerables. It varies from Jon Hanna's in that it doesn't create a new List, it just keeps track of two iterators.
public int compareElementEnumerable(IEnumerable<Element> elements)
{
int result = 0, i = 0, q = 1;
foreach (Element el in elements)
{
foreach (Element el2 in elements)
{
if (q > i)
{
result = Math.Max(result, compareElements(el, el2));
}
q++;
}
i++;
}
return result;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With