如何在C#中做一个比较函数

Bri*_*gon 5 c# linq comparison

假设我在列表中有元素(X,Y和Z),我有一个函数,它生成一个百分比,两个对象彼此相似的程度.

我想要做的是使用我的compareElements对Y和Z运行X,所以:

compareElements(X,Y); // equals 55
compareElements(X,Z); // equals 60
Run Code Online (Sandbox Code Playgroud)

然后Y对抗X和Z.

compareElements(Y,X); // equals 55
compareElements(Y,Z); // equals 62
Run Code Online (Sandbox Code Playgroud)

然后Z对Y和X

compareElements(Z,X); // equals 60
compareElements(Z,Y); // equals 62
Run Code Online (Sandbox Code Playgroud)

然后,我返回最高值,即62.

显然,那里有一些重复,我不需要重复,但我不知道如何消除它.

如何构建我的LINQ查询或函数/算法来对每个元素进行这种比较,而不重复?

如果可以的话,我更喜欢使用LINQ,因为我传递了一个可枚举的函数,并且在列表实际枚举之前函数返回,因此我们可以节省执行比较的成本,直到列表被枚举.

我只需要比较函数的最高值,62.

注意:我的实际结果集我正在使用列表中3到10个元素之间的平均值,需要通过此比较函数运行.

Eri*_*ert 8

我倾向于这样做:

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();
Run Code Online (Sandbox Code Playgroud)


sme*_*lch 5

我不确定我是否正确理解你,但尝试这样的事情:

    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;
    }
Run Code Online (Sandbox Code Playgroud)

这将消除重复的比较.它不使用LINQ,但我认为它仍然很可读.

更新:这是我的版本修改,以处理IEnumerables.它与Jon Hanna的不同之处在于它不会创建新的List,它只跟踪两个迭代器.

    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;
    }
Run Code Online (Sandbox Code Playgroud)


Sea*_*n U 2

为了便于阅读,我将编写一个迭代器块以非重复的方式生成比较:

IEnumerable<Tuple<T, T>> GetComparisons<T>(IEnumerable<T> elements)
{
    var visited = new List<T>();

    foreach(T current in elements)
    {
        foreach(T previous in visited) 
            yield return new Tuple<T, T>(current, previous);

        visited.Add(current);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以执行以下操作:

var highScore = GetComparisons(listOfElements)
                    .Select(x=>compareElements(x.Item1, x.Item2)
                    .Max();
Run Code Online (Sandbox Code Playgroud)

(也就是说,对于没有实际理由使用 LINQ 或迭代器的情况(例如需要可组合例程),我更喜欢 Smelch 的建议。)