2013-02-13 2 views
0

У меня есть 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); 
     } 
    } 
} 

Было бы неплохо найти простую предопределенную функцию, однако!

+5

Уверены ли вы, что вы действительно должны иметь три массива, а не один массив, в котором каждый элемент состоит из трех разных значений? Я всегда нервничаю, когда у вас есть несколько коллекций, которые нужно хранить в режиме блокировки ... –

+0

Что вы не можете сделать '.Distinct(). ToArray()' для других двух массивов? – Brian

+0

Как насчет публикации фактического кода, ваша проблема в другом месте, Distinct() должна работать –

ответ

1
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; 
0

Вы должны рассмотреть, какую структуру данных вы используете. Возможно ли, что операция «удалить» произойдет сразу? Как часто? (Я не оспариваю ваше использование Array обязательно, просто общий совет, но ваш сценарий кажется странным). Кроме того, вы не объяснили, является ли это удаление на основе индекса или удаление элемента. Если бы я реализовал это, у меня возникло бы желание создать новый массив и добавить все остальные элементы в новый массив в цикле, игнорируя элементы, которые вы хотите удалить. Затем просто переназначьте ссылку с помощью «=». Конечно, это зависит от максимального ожидаемого размера массива, поскольку такая копия, как я предполагала, занимает больше памяти (обычно это не проблема).

0

Я действительно не знаю, как сделать то, что вы просите, но это общий пример того, что вы просили?

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; 
}