Сравнение двух списков с использованием LINQ - PullRequest
0 голосов
/ 12 мая 2011

Если у меня есть 2 списка строк:

List<string> firstList = new List<string>("010", "111", "123");
List<string> secondList = new List<string>("010", "111", "999");

Как я могу сравнить каждого отдельного персонажа в каждом предмете из списков? Пример: следует сравнить «0» с «0», «1» с «1», «0» с «0» и т. Д. Похоже, что я могу использовать SelectMany, но я застрял на том, как это сделать

EDIT:

Эти списки должны возвращать true при сравнении друг с другом (так как звездочка означает любой символ, и я проверяю, чтобы убедиться, что каждый элемент имеет в точности 3 символа в длину)

List<string> firstList = new List<string>("010", "111", "123");
List<string> secondList = new List<string>("010", "1*1", "***");

Ответы [ 3 ]

5 голосов
/ 12 мая 2011

Обновлено с подстановочными знаками

class WildcardStringComparer : IEqualityComparer<string>
{
    public bool Equals(string s1, string s2)
    {
        if (s1.Length != s2.Length) return false;

        for (int i = 0; i < s1.Length; i++)
        {
            if (s1[i] != s2[i] && s1[i] != '*' && s2[i] != '*')
                return false;
        }

        return true;
    }


    public int GetHashCode(string obj)
    {
        throw new NotImplementedException();
    }
}

Результаты:

List<string> firstList = new List<string>{"010", "111", "999"};
List<string> secondList = new List<string>{"010", "111", "999"};

bool res = firstList.SequenceEqual(secondList, new WildcardStringComparer()); // True

и

List<string> firstList = new List<string>{"010", "111", "999"};
List<string> secondList = new List<string>{"010", "111", "*99"};

bool res = firstList.SequenceEqual(secondList, new WildcardStringComparer()); // True

и

List<string> firstList = new List<string>{"010", "111", "999"};
List<string> secondList = new List<string>{"010", "111", "199"};

bool res = firstList.SequenceEqual(secondList, new WildcardStringComparer()); // False
1 голос
/ 12 мая 2011

Если вы просто хотите сравнить для совпадающей последовательности символов между списками:

bool sameCharacters = Enumerable.SequenceEqual(firstList.SelectMany(x => x), 
                                               secondList.SelectMany(x => x));

Это приведет к true, то есть для следующих двух списков - их последовательности символов совпадают ("010111123"для обоих) их отдельные строковые записи не:

List<string> firstList = new List<string> {"010", "111", "123" };
List<string> secondList = new List<string> {"010", "11", "1123" };

Редактировать в ответ на комментарии:

Для подстановочного совпадения вы можете использовать Zip() и сравнитьдля каждого символа возвращайте значение true, если они совпадают, основываясь на условиях подстановочных знаков, а затем просто убедитесь, что каждый элемент в сжатой последовательности имеет вид true.

var isWildCardMatch = firstList.SelectMany (x => x)Zip (secondList.SelectMany (x => x), (a, b) => {if (a == b || a == '' || b == '') вернуть true;return false;

    }).All( x=> x);

При подходе пересекаются границы ввода строк, что может привести к ложным совпадениям - здесь лучший подход:

bool isWildCardMatch = firstList.Zip(secondList, (x, y) =>
{
    var matchWord = y.Select((c, i) => c == '*' ? x[i] : c);
    return matchWord.SequenceEqual(x);
}).All(x => x);
0 голосов
/ 12 мая 2011

Предполагая, что вы хотите сравнить первый символ первой строки в первом списке с первым символом первой строки второго списка, второй символ первой строки в первом списке со вторым символом первогострока во втором списке и т. д. Я могу подумать о двух реализациях.

Тот, с которого я бы начал:

var firstCharList = new List<char>();
var secondCharList = new List<char>();

firstList.foreach(s => 
 {
   foreach(char c in s)
   {
      firstCharList.Add(c);
   }
  });

secondList.foreach(s =>
{
   foreach(char c in s)
   {
      secondCharList.Add(c);
   }
});

for(int i = 0; i < firstCharList.Length; i++)
{
   if(firstCharList[i] == secondCharList[i]) yield return i;
}

Это создаст список (или массив, или что-то) изцелые числа, которые соответствуют индексам, у которых обе строки имели одинаковый символ.

Вторая будет выглядеть примерно так:

firstList.foreach(s =>
{
   var index = firstList.IndexOf(s);
   var sPrime = secondList[index];
   for(int i = 0; i < s.Length; i++)
   {
      if(s[i] == sPrime[i]) yield return s[i];
   }
}

Эта строка просто возвращает любые символы, равные по одинаковым индексам.

...