高级删除重复数组
本文关键字:数组 删除 高级 | 更新日期: 2023-09-27 17:59:03
我有3个数组。
Array 1 = {1,1,1,1,2,2,3,3}
Array 2 = {a,a,a,a,e,e,b,b}
Array 3 = {z,z,z,z,z,z,z,z}
我想从数组1中删除所有重复项,并在其他数组中删除所述重复项处的相同元素,以保持它们都正确链接。
我知道你可以对一个数组使用.Distinct().ToArray()来实现这一点,但其他数组也不会删除元素。
结果会是这样的。
Array 1 = {1,2,3}
Array 2 = {a,e,b}
Array 3 = {z,z,z}
我猜解决这个问题的唯一方法是以下方法。
For(int a = 0; a < Array1.count; a++) {
For(int b = a + 1; b < Array1.count; b++) {
if(Array1[a]==Array1[b]) {
Array1.RemoveAt(b);
Array2.RemoveAt(b);
Array3.RemoveAt(b);
}
}
}
不过,如果能找到一个简单的预定义函数,那就太好了!
var distinctIndexes = array1
.Select((item, idx) => new { Item = item, Index = idx })
.GroupBy(p => p.Item)
.Select(grp => grp.First().Index);
var result1 = distinctIndexes.Select(i => array1[i]).ToArray();
var result2 = distinctIndexes.Select(i => array2[i]).ToArray();
var result3 = distinctIndexes.Select(i => array3[i]).ToArray();
请注意,这不一定要使用第一个数组中的第一个唯一元素。如果你需要这样做,你可以将指数计算为
var distinctIndexes = array1
.Select((item, idx) => new { Item = item, Index = idx })
.Aggregate(new Dictionary<int, int>(), (dict, i) =>
{
if (! dict.ContainsKey(i.Item))
{
dict[i.Item] = i.Index;
}
return dict;
})
.Values;
您应该仔细考虑使用的数据结构。这种"删除"操作是否可能同时发生?多久一次?(我并不一定要挑战你对Array的使用,只是一个一般的提示,但你的场景似乎很奇怪)。此外,您没有解释这是基于索引的删除还是基于元素的删除。如果我实现了这一点,我会尝试创建一个新的数组,并在循环中将所有剩余的元素添加到新的数组中,忽略要删除的元素。然后简单地用"="重新分配引用。当然,这取决于数组的最大预期大小,因为我建议的副本会占用更多内存(通常不会有问题)。
我真的不知道有什么干净的方法来满足你的要求,但这是一个满足你要求的通用示例?
static void RemoveDupes(ref Array a1, ref Array a2, ref Array a3)
{
Type a1t, a2t, a3t;
int newLength, ni, oi;
int[] indices;
a1t = a1.GetType().GetElementType();
a2t = a1.GetType().GetElementType();
a3t = a1.GetType().GetElementType();
Dictionary<object, List<int>> buckets = new Dictionary<object, List<int>>();
for (int i = 0; i < a1.Length; i++)
{
object val = a1.GetValue(i);
if (buckets.ContainsKey(val))
buckets[val].Add(i);
else
buckets.Add(val, new List<int> { i });
}
indices = buckets.Where(kvp => kvp.Value.Count > 1).SelectMany(kvp => kvp.Value.Skip(1)).OrderBy(i => i).ToArray();
newLength = a1.Length - indices.Length;
Array na1 = Array.CreateInstance(a1t, newLength);
Array na2 = Array.CreateInstance(a2t, newLength);
Array na3 = Array.CreateInstance(a3t, newLength);
oi = 0;
ni = 0;
for (int i = 0; i < indices.Length; i++)
{
while (oi < indices[i])
{
na1.SetValue(a1.GetValue(oi), ni);
na2.SetValue(a2.GetValue(oi), ni);
na3.SetValue(a3.GetValue(oi), ni);
oi++;
ni++;
}
oi++;
}
while (ni < newLength)
{
na1.SetValue(a1.GetValue(oi), ni);
na2.SetValue(a2.GetValue(oi), ni);
na3.SetValue(a3.GetValue(oi), ni);
oi++;
ni++;
}
a1 = na1;
a2 = na2;
a3 = na3;
}