5

我有这样的结构

List<int[]> propIDs = new List<int[]>();

我可以使用 LINQ 从 propID 中获取所有唯一值吗?例如,我有 (1,2) (4,5) (1,5) (1,2) (1,5) 的列表,我必须得到 (1,2 ) (4,5) (1,5)

4

6 回答 6

3

您可以使用采用相等比较器的Enumerable.Distinct的重载。

class IntPairArrayComparer : IEqualityComparer<int[]>
{
    public bool Equals(int[] left, int[] right)
    {
        if (left.Length != 2) throw new ArgumentOutOfRangeException("left");
        if (right.Length != 2) throw new ArgumentOutOfRangeException("right");

        return left[0] == right[0] && left[1] == right[1];
    }

    public int GetHashCode(int[] arr)
    {
        unchecked
        {
            return (arr[0].GetHashCode() * 397) ^ arr[1].GetHashCode();
        }
    }
}

IEnumerable<int[]> distinctPairs = propIDs.Distinct(new IntPairArrayComparer());

如果您想要大于对的集合:

class IntArrayComparer : IEqualityComparer<int[]>
{
    public bool Equals(int[] left, int[] right)
    {
        if (left.Length != right.Length) return false;

        return left.SequenceEquals(right);
    }

    public int GetHashCode(int[] arr)
    {
        unchecked
        {
            int hc = 1;

            foreach (int val in arr) hc = hc * 397 ^ val.GetHashCode();
        }
    }
}

如果您的所有int数组都是两个元素长,您也可以使用Tuples 代替,这将允许您在Distinct没有自定义相等比较器的情况下使用:

IEnumerable<Tuple<int, int>> propIDs = [] { Tuple.Create(1,2), … };
IEnumerable<Tuple<int, int>> distinctPairs = propIDs.Distinct();
于 2013-02-21T11:41:29.187 回答
1

以下是您需要的完整且有效的应用程序。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ListsAndArrays
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int[]> propIDs = new List<int[]>();
            propIDs.Add(new[] { 1, 2 });
            propIDs.Add(new[] { 4, 5 });
            propIDs.Add(new[] { 1, 5 });
            propIDs.Add(new[] { 1, 2 });
            propIDs.Add(new[] { 1, 5 });

            var distinct = propIDs.Distinct(new DistinctIntegerArrayComparer());

            foreach (var item in distinct)
            {
                Console.WriteLine("{0}|{1}", item[0], item[1]);
            }

            if (Debugger.IsAttached)
            {
                Console.ReadLine();
            }
        }

        private class DistinctIntegerArrayComparer : IEqualityComparer<int[]>
        {
            public bool Equals(int[] x, int[] y)
            {
                if (x.Length != y.Length) { return false; }
                else if (x.Length != 2 || y.Length != 2) { return false; }

                return x[0] == y[0] && x[1] == y[1];
            }

            public int GetHashCode(int[] obj)
            {
                return -1;
            }
        }

    }
}
于 2013-02-21T11:45:37.847 回答
1

此代码适用于任何长度的数组。

    class MyEqualityComparer : IEqualityComparer<int[]>
    {
        public bool Equals(int[] item1, int[] item2)
        {
            if (item1 == null && item2 == null)
                return true;
            if ((item1 != null && item2 == null) ||
                    (item1 == null && item2 != null))
                return false;
            return item1.SequenceEqual(item2);
        }

        public int GetHashCode(int[] item)
        {
            if(item == null)
            {
                return int.MinValue;
            }
            int hc = item.Length;
            for (int i = 0; i < item.Length; ++i)
            {
                hc = unchecked(hc * 314159 + item[i]);
            }
            return hc;
        }
    }

和不同的代码:

var result = propIDs.Distinct(new MyEqualityComparer());
于 2013-02-21T11:49:45.373 回答
1

假设您不能使用which 已经提供了相等性,您可以通过简单地要求所有元素按顺序相等Tuple<T1, T2>来创建自己的定义数组相等性的方法:IEqualityComparer<T>

class ArrayEqualityComparer<T> : IEqualityComparer<T[]> {

  public Boolean Equals(T[] x, T[] y) {
    if (x.Length != y.Length)
      return false;
    return x.Zip(y, (xx, yy) => Equals(xx, yy)).All(equal => equal);
  }

  public Int32 GetHashCode(T[] obj) {
    return obj.Aggregate(0, (hash, value) => 31*hash + value.GetHashCode());
  }

}

然后您可以轻松获得不同的值:

var distinctPropIDs  = propIDs.Distinct(new ArrayEqualityComparer<Int32>());
于 2013-02-21T11:50:29.797 回答
0
public return List<Tuple<double, double>> uniquePairs(List<double[]> lst)
{
HashSet<Tuple<double, double>> hash = new HashSet<Tuple<double, double>>();
for (int i = 0; i < lst.count; i++)
{
hash.Add(new Tuple<double, double>(lst[i][0], lst[i][1]))
}
List<Tuple<double, double>> lstt = hash.Distinct().ToList();
}

For example:
List<double[]> lst = new List<double[]> {new double[] { 1, 2 }, new double[] { 2, 3 }, new double[] { 3, 4 }, new double[] { 1, 4 }, new double[] { 3, 4 }, new double[] { 2, 1 }}; //  this list has 4 unique numbers, 5 unique pairs, the desired output would be the 5 unique pairs (count = 5)
List<Tuple<double, double>> lstt = uniquePairs(lst);
Console.WriteLine(lstt.Count().ToString());

输出为 5

于 2016-04-01T20:24:21.477 回答
-1

HashSet,集合是不包含重复元素的集合:

var propIDs = HashSet<Tuple<int,int>>
于 2013-02-21T11:45:01.967 回答