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配列が 2 つの要素の長さである場合、Tuple代わりに s を使用することもできます。これによりDistinct、カスタム等値比較子なしでを使用できるようになります。

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

すでに同等性を提供しているものを使用できないと仮定すると、代わりに、すべての要素が順番に等しいことを要求するだけで、配列の同等性を定義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 に答える
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 に答える
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

セットは、重複する要素を含まないコレクションです。

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