cMi*_*nor 24 .net c# linq arrays
有一个int数组列表,如:
List<int[]> intArrList = new List<int[]>();
intArrList.Add(new int[3] { 0, 0, 0 });
intArrList.Add(new int[5] { 20, 30, 10, 4, 6 }); //this
intArrList.Add(new int[3] { 1, 2, 5 });
intArrList.Add(new int[5] { 20, 30, 10, 4, 6 }); //this
intArrList.Add(new int[3] { 12, 22, 54 });
intArrList.Add(new int[5] { 1, 2, 6, 7, 8 });
intArrList.Add(new int[4] { 0, 0, 0, 0 });
Run Code Online (Sandbox Code Playgroud)
你将如何删除重复(重复我的意思是列表元素具有相同的长度和相同的数字).
在示例中,我将删除元素,{ 20, 30, 10, 4, 6 }
因为它被发现两次
我正在考虑按元素大小对列表进行排序,然后将每个元素循环反对休息,但我不知道该怎么做.
其他问题是,如果使用像哈希这样的其他结构会更好......如果是这样如何使用它?
Sal*_*ari 26
用途GroupBy
:
var result = intArrList.GroupBy(c => String.Join(",", c))
.Select(c => c.First().ToList()).ToList();
Run Code Online (Sandbox Code Playgroud)
结果:
{0,0,0}
{20,30,10,4,6}
{1,2,5}
{12,22,54}
{1,2,6,7,8}
{0,0,0,0}
编辑:如果你想考虑{1,2,3,4}
等于{2,3,4,1}
你需要OrderBy
像这样使用:
var result = intArrList.GroupBy(p => string.Join(", ", p.OrderBy(c => c)))
.Select(c => c.First().ToList()).ToList();
Run Code Online (Sandbox Code Playgroud)
编辑2:为了帮助理解LINQ GroupBy
解决方案的工作原理,请考虑以下方法:
public List<int[]> FindDistinctWithoutLinq(List<int[]> lst)
{
var dic = new Dictionary<string, int[]>();
foreach (var item in lst)
{
string key = string.Join(",", item.OrderBy(c=>c));
if (!dic.ContainsKey(key))
{
dic.Add(key, item);
}
}
return dic.Values.ToList();
}
Run Code Online (Sandbox Code Playgroud)
Him*_*ere 12
您可以定义自己的实现IEqualityComparer
并将其与IEnumerable.Distinct
以下内容一起使用:
class MyComparer : IEqualityComparer<int[]>
{
public int GetHashCode(int[] instance) { return 0; } // TODO: better HashCode for arrays
public bool Equals(int[] instance, int[] other)
{
if (other == null || instance == null || instance.Length != other.Length) return false;
return instance.SequenceEqual(other);
}
}
Run Code Online (Sandbox Code Playgroud)
现在编写此代码以仅获取列表的不同值:
var result = intArrList.Distinct(new MyComparer());
Run Code Online (Sandbox Code Playgroud)
但是,如果您想要不同的排列,也应该以这种方式实现比较器:
public bool Equals(int[] instance, int[] other)
{
if (ReferenceEquals(instance, other)) return true; // this will return true when both arrays are NULL
if (other == null || instance == null) return false;
return instance.All(x => other.Contains(x)) && other.All(x => instance.Contains(x));
}
Run Code Online (Sandbox Code Playgroud)
编辑:为了更好的GetashCode
实现,你可以看看这篇文章,也在@Mick的回答中提出.
从这里和这里提升代码.一个更通用的GetHashCode实现会使这更通用,但我相信下面的实现是最强大的
class Program
{
static void Main(string[] args)
{
List<int[]> intArrList = new List<int[]>();
intArrList.Add(new int[3] { 0, 0, 0 });
intArrList.Add(new int[5] { 20, 30, 10, 4, 6 }); //this
intArrList.Add(new int[3] { 1, 2, 5 });
intArrList.Add(new int[5] { 20, 30, 10, 4, 6 }); //this
intArrList.Add(new int[3] { 12, 22, 54 });
intArrList.Add(new int[5] { 1, 2, 6, 7, 8 });
intArrList.Add(new int[4] { 0, 0, 0, 0 });
var test = intArrList.Distinct(new IntArrayEqualityComparer());
Console.WriteLine(test.Count());
Console.WriteLine(intArrList.Count());
}
public class IntArrayEqualityComparer : IEqualityComparer<int[]>
{
public bool Equals(int[] x, int[] y)
{
return ArraysEqual(x, y);
}
public int GetHashCode(int[] obj)
{
int hc = obj.Length;
for (int i = 0; i < obj.Length; ++i)
{
hc = unchecked(hc * 17 + obj[i]);
}
return hc;
}
static bool ArraysEqual<T>(T[] a1, T[] a2)
{
if (ReferenceEquals(a1, a2))
return true;
if (a1 == null || a2 == null)
return false;
if (a1.Length != a2.Length)
return false;
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < a1.Length; i++)
{
if (!comparer.Equals(a1[i], a2[i])) return false;
}
return true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑: IEqualityComparer的通用实现,适用于任何类型的数组: -
public class ArrayEqualityComparer<T> : IEqualityComparer<T[]>
{
public bool Equals(T[] x, T[] y)
{
if (ReferenceEquals(x, y))
return true;
if (x == null || y == null)
return false;
if (x.Length != y.Length)
return false;
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < x.Length; i++)
{
if (!comparer.Equals(x[i], y[i])) return false;
}
return true;
}
public int GetHashCode(T[] obj)
{
int hc = obj.Length;
for (int i = 0; i < obj.Length; ++i)
{
hc = unchecked(hc * 17 + obj[i].GetHashCode());
}
return hc;
}
}
Run Code Online (Sandbox Code Playgroud)
Edit2:如果数组内的整数排序无关紧要,我会的
var test = intArrList.Select(a => a.OrderBy(e => e).ToArray()).Distinct(comparer).ToList();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1094 次 |
最近记录: |