不同的列表<string> of chars </string>

时间:2013-03-21 20:49:18

标签: c# linq list distinct

我有这个:

List<string> list = new List<string>();
list.Add("a-b-c>d");
list.Add("b>c");
list.Add("f>e");
list.Add("f>e-h");
list.Add("a-d>c-b");

我想删除重复项。在这种情况下,重复是“a-b-c> d”和“a-d> c-b”。两者都有相同的字符,但是以不同的顺序排列。 我尝试过:

list.Distinct().ToList();

但没有用!

3 个答案:

答案 0 :(得分:10)

看起来你想要:

var distinct = list
    .Select((str, idx) => new { Str = str, Idx = idx })
    .GroupBy(pair => new HashSet<char>(pair.Str), HashSet<char>.CreateSetComparer())
    .Select(grp => grp.OrderBy(p => p.Idx).First())
    .ToList();

这将保留第一个元素,并删除序列中包含相同字符的任何后续字符串。

您还可以使用Aggregate跟踪您已经看过的字符集:

var distinct = list
    .Aggregate(new Dictionary<HashSet<char>, string>(HashSet<char>.CreateSetComparer()), (dict, str) =>
    {
        var set = new HashSet<char>(str);
        if (!dict.ContainsKey(set))
            dict.Add(set, str);
        return dict;
    })
    .Values
    .ToList();

答案 1 :(得分:5)

您必须定义一个自定义IEqualityComparer,允许系统在您认为两个字符串“相等”时理解它。例如:

List<string> list = new List<string>();
list.Add("a-b-c>d");
list.Add("b>c-d-f");
list.Add("c-d-f>e");
list.Add("a-d>c-b");
var distinctItems = list.Distinct(new KeyFuncEqualityComparer<string>(
    s => new String(s.AsEnumerable().OrderBy(c => c).ToArray())));

结果:

a-b-c>d 
b>c-d-f 
c-d-f>e 

...使用这个通用的IEqualityComparer实现:

public class KeyFuncEqualityComparer<T> :IEqualityComparer<T>
{
    private readonly Func<T, object> _getKey;

    public KeyFuncEqualityComparer(Func<T, object> getKey)
    {
        _getKey = getKey;
    }

    public bool Equals(T x, T y)
    {
        return _getKey(x).Equals(_getKey(y));
    }

    public int GetHashCode(T obj)
    {
        return _getKey(obj).GetHashCode();
    }
}

答案 2 :(得分:0)

未测试

    list<int> dups = new list<int>();
    for(int i = 0; i < list.count - 1; i++)
    {
         for(int j = 1; j < list.count; j++)
         {
                int len = list[j].length;
             bool b = false;
           for(int k = 0; k < list[i].length; k++)
            {
                if(k < len && (list[i][k] != list[j][k]))
               {
                b = false;
                break;
            }
         b = true;
     }
    if(b == true)
    {
    dups.add(i);
     }
    }
    }

然后从列表中删除所有重复