2011-01-16 1 views
2

Я пытаюсь найти решение этой проблемы:IEnumerable <IEnumerable <int>> - не дублировать IEnumerable <int> s

Учитывая IEnumerable < < IEnumerable INT >> Мне нужен метод/алгоритм, который возвращает вход, но в случае нескольких IEnmerable < int> с теми же элементами возвращается только одна за совпадение/группа.

ex.

IEnumerable<IEnumerable<int>> seqs = new[] 
    { 
     new[]{2,3,4}, // #0 
     new[]{1,2,4}, // #1 - equals #3 
     new[]{3,1,4}, // #2 
     new[]{4,1,2} // #3 - equals #1 
    }; 

"Еогеасп след в seqs" .. дает {# 0, # 1, # 2} или {# 0, # 2, # 3}

Sould хожу с ..

.. какой-то умный IEqualityComparer

.. какой-нибудь умный LINQ сочетание я havent выставляется - группаby, sequenceequal ..?

.. некоторые seq-> HashSet материал

.. что нет. Что-нибудь поможет

Я смогу решить это путем программирования good'n'old, но вдохновение всегда ценится.

ответ

7

Вот несколько проще вариант ответа digEmAll в:

var result = seqs.Select(x => new HashSet<int>(x)) 
       .Distinct(HashSet<int>.CreateSetComparer()); 

Учитывая, что вы хотите обработать элементы в качестве наборов, вы должны иметь их таким образом, чтобы начать с, ИМО.

Конечно, это не поможет, если вы хотите, чтобы поддерживать порядок в последовательности, которые возвращаются, вы просто не против который равных множеств возвращается ... выше код возвратит IEnumerable<HashSet<int>> который больше не будет упорядочиваться в каждой последовательности. (Порядок возврата также не гарантируется, хотя было бы странно, если бы они не возвращались в первый раз, когда они возвращались.)

Чувствуется маловероятным, достаточно, но если бы вы могли дать более подробную информацию о том, что вам действительно нужно достичь, это облегчило бы помощь.

Как уже отмечалось в комментариях, это также предполагает, что в дубликатов каждого исходного исходного массива ... или, по крайней мере, они неактуальны, поэтому вы с удовольствием относитесь к {1} и { 1, 1, 1, 1} равным.

+1

+1 Приятно, но вы должны предупредить OP abut a) разные частоты дубликатов, вызывающие проблемы b) тот факт, что это мешает упорядочению чисел внутри каждого массива c) факт, что это действительно не возвращает членов исходной последовательности-источника. – Ani

+0

@Ani: Я уже упоминал об обрыве порядка чисел в массиве, но теперь я сделал это более явным. Будет добавлено немного о дубликатах в каждом массиве. –

+0

Упс, извините .. – Ani

4

Используйте правильный тип коллекции для задания. То, что вы действительно хотите, это ISet<IEnumerable<int>> с помощью анализатора равенства, который будет игнорировать порядок IEnumerable.

3

EDITED:

Вы можете получить то, что вы хотите, создать свой собственный IEqualityComparer<IEnumerable<int>> .: например

public class MyEqualityComparer : IEqualityComparer<IEnumerable<int>> 
{ 
    public bool Equals(IEnumerable<int> x, IEnumerable<int> y) 
    { 
     return x.OrderBy(el1 => el1).SequenceEqual(y.OrderBy(el2 => el2)); 
    } 

    public int GetHashCode(IEnumerable<int> elements) 
    { 
     int hash = 0; 
     foreach (var el in elements) 
     { 
      hash = hash^el.GetHashCode(); 
     } 
     return hash; 
    } 
} 

Использование:

var values = seqs.Distinct(new MyEqualityComparer()).ToList(); 

N.B.

Это решение немного отличается от решения, данного Jon Skeet.
В его ответе посчитали, что комплектов, поэтому в основном два списка, таких как [1,2] и [1,1,1,2,2], равны.

Это решение не делает, т.е.:
[1,2,1,1] равно [2,1,1,1], но не [2,2,1,1], следовательно, в основном, два списка должен содержать одни и те же элементы и в том же количестве случаев.

+0

+1: Никогда не слышал о 'HashSet .CreateSetComparer'. Но это не совсем правильно; Я думаю, что последний бит должен быть '.Select (g => g.First()). ToList();' – Ani

+0

Предложение 'Where' не должно быть там, я думаю. – Ani

+0

@Ani: Да, вы правы, на самом деле я неправильно читаю вопрос OP (я не знаю почему, но я думал, что он хочет исключить подсписки, встречающиеся более одного раза ... O_O). Так что Distinct намного предпочтительнее, чем groupby-select first ... – digEmAll

 Смежные вопросы

  • Нет связанных вопросов^_^