代码之家  ›  专栏  ›  技术社区  ›  Thorin Oakenshield

如何使用LINQ从列表<string>中删除重复的组合

  •  3
  • Thorin Oakenshield  · 技术社区  · 14 年前

    我有一个字符串列表

    List<string> MyList = new List<string>
    { 
        "A-B", 
        "B-A", 
        "C-D", 
        "C-E", 
        "D-C",
        "D-E",
        "E-C",
        "E-D",
        "F-G",
        "G-F"
    };
    

    "A-B"   
    "C-D"
    "C-E"   
    "D-E"
    "F-G"
    

    使用LINQ有什么方法可以做到这一点吗?

    6 回复  |  直到 14 年前
        1
  •  12
  •   Fredrik Mörk    14 年前

    这将返回您要查找的序列:

    var result = MyList
        .Select(s => s.Split('-').OrderBy(s1 => s1))
        .Select(a => string.Join("-", a.ToArray()))
        .Distinct();
    
    foreach (var str in result)
    {
        Console.WriteLine(str);
    }
    

    简言之:在屏幕上拆分每个字符串 - Distinct 获取唯一值。

    更新:当我多想一想,我意识到你可以很容易地删除其中一个 Select 电话:

    var result = MyList
        .Select(s => string.Join("-", s.Split('-').OrderBy(s1 => s1).ToArray()))
        .Distinct();
    

        2
  •  14
  •   gandjustas    14 年前

    实现IEqualityComparer,该开关在等于时返回true(“A-B”,“B-A”)。使用 Enumerable.Distinct

        3
  •  4
  •   Community CDub    8 年前

    你可以用 Enumerable.Distinct(IEnumerable<TSource>, IEqualityComparer<TSource>) 超载。

    现在你只需要实现 IEqualityComparer

    class Comparer : IEqualityComparer<String>
    {
    
        public bool Equals(String s1, String s2)
        {
            // will need to test for nullity
            return Reverse(s1).Equals(s2);
        }
    
        public int GetHashCode(String s)
        {
            // will have to implement this
        }
    
    }
    

    为了一个 Reverse() 实施,见 this question

        4
  •  1
  •   code4life    14 年前

    public class CharComparer : IEqualityComparer<string>
    {
        #region IEqualityComparer<string> Members
    
        public bool Equals(string x, string y)
        {
            if (x == y)
                return true;
    
            if (x.Length == 3 && y.Length == 3)
            {
                if (x[2] == y[0] && x[0] == y[2])
                    return true;
    
                if (x[0] == y[2] && x[2] == y[0])
                    return true;
            }
    
            return false;
        }
    
        public int GetHashCode(string obj)
        {
            // return 0 to force the Equals to fire (otherwise it won't...!)
            return 0;
        }
    
        #endregion
    }
    

    示例程序:

    class Program
    {
        static void Main(string[] args)
        {
            List<string> MyList = new List<string>
            { 
                "A-B", 
                "B-A", 
                "C-D", 
                "C-E", 
                "D-C",
                "D-E",
                "E-C",
                "E-D",
                "F-G",
                "G-F"
            };
    
            var distinct = MyList.Distinct(new CharComparer());
            foreach (string s in distinct)
                Console.WriteLine(s);
    
            Console.ReadLine();
        }
    }
    

    结果是:

    "A-B"   
    "C-D"
    "C-E"   
    "D-E"
    "F-G"
        5
  •  1
  •   Sebastian Brózda    14 年前

    非常基本,但可以写得更好(但它只是工作):

    class Comparer : IEqualityComparer<string>
      {
          public bool Equals(string x, string y)
          {
              return (x[0] == y[0] && x[2] == y[2]) || (x[0] == y[2] && x[2] == y[0]);
          }
    
          public int GetHashCode(string obj)
          {
              return 0;
          }
      }
    
    var MyList = new List<String>
    { 
        "A-B", 
        "B-A", 
        "C-D", 
        "C-E", 
        "D-C",
        "D-E",
        "E-C",
        "E-D",
        "F-G",
        "G-F"
    }
    .Distinct(new Comparer());
    
    foreach (var s in MyList)
    {
        Console.WriteLine(s);
    }
    
        6
  •  -2
  •   Minh Nguyen    14 年前
    int checkID = 0;
    while (checkID < MyList.Count)
    {
     string szCheckItem = MyList[checkID];
     string []Pairs = szCheckItem.Split("-".ToCharArray());
     string szInvertItem = Pairs[1] + "-" + Pairs[0];
     int i=checkID+1;
     while (i < MyList.Count)
     {
      if((MyList[i] == szCheckItem) || (MyList[i] == szInvertItem))
      {
       MyList.RemoveAt(i);
       continue;
      }
      i++;
     }
    
     checkID++;
    }
    
    推荐文章