2016-03-07 2 views
0

Я ищу, чтобы найти различия между двумя списками строковых массивов, используя индекс 0 массива в качестве первичного ключа.Поиск различий внутри 2 списков строковых массивов

List<string[]> original = new List<string[]>(); 
List<string[]> web = new List<string[]>(); 

//define arrays for List 'original' 
string[] original_a1 = new string[3]{"a","2","3"}; 
string[] original_a2 = new string[3]{"x","2","3"}; 
string[] original_a3 = new string[3]{"c","2","3"}; 

//define arrays for List 'web' 
string[] web_a1 = new string[3]{"a","2","3"}; 
string[] web_a2 = new string[3]{"b","2","3"}; 
string[] web_a3 = new string[3]{"c","2","3"}; 

//populate Lists 
original.Add(original_a1); 
original.Add(original_a2); 
original.Add(original_a3); 

web.Add(web_a1); 
web.Add(web_a2); 
web.Add(web_a3); 

Моя цель состоит в том, чтобы найти то, что в список «оригинал», но не в «сети» с использованием индекса 0 в качестве первичного ключа
Это то, что я пытался.

List<string> differences = new List<string>(); //differences go in here 
string tempDiff = ""; // I use this to try and avoid duplicate entries but its not working 

for(int i = 0; i < original.Count; i++){ 
for(int j = 0; j< web.Count; j++){ 
    if(!(original[i][0].Equals(web[j][0]))){ 
     tempDiff = original[i][0]; 
    } 
} 
differences.Add(tempDiff); 
} 

ВЫВОД:

foreach(string x in differences){ 
    Console.WriteLine("SIZE " + differences.Count); 
    Console.WriteLine(x); 
    ConSole.ReadLine(); 
} 

SIZE 3 

SIZE 3 
x 

SIZE 3 

x 

Почему несоответствие отчетности 3 раза вместо одного?

ответ

4

с помощью LINQ вы можете просто пойти:

var differences = orignal.Except(web).ToList(); 

Ссылка here

Это даст вам значения, которые находятся в original, которые не существуют в web

К сожалению, не сделал правильно прочитайте свой вопрос, чтобы ответить на ваш вопрос: У вас есть вложенный цикл for. Таким образом, для каждого значения оригинала (3) он будет проходить через все значения сети (3), которая равна 9 петлям.

В 3 случаях он не соответствует и, следовательно, выдает 3 раза.

0

Я думаю, что это то, что вы хотите. Я использую Linq для захвата первичных ключей, а затем я использую Except, чтобы сделать original - web. Кстати, вы можете использовать == вместо Equals со строками в C#, потому что C# сопоставляет значение в сравнении с эталонным сравнением.

List<string[]> original = new List<string[]> 
{ 
    new string[3] { "a", "2", "3" }, 
    new string[3] { "x", "2", "3" }, 
    new string[3] { "c", "2", "3" } 
}; 
List<string[]> web = new List<string[]> 
{ 
    new string[3] { "a", "2", "3" }, 
    new string[3] { "b", "2", "3" }, 
    new string[3] { "c", "2", "3" } 
}; 

var originalPrimaryKeys = original.Select(o => o[0]); 
var webPrimaryKeys = web.Select(o => o[0]); 

List<string> differences = originalPrimaryKeys.Except(webPrimaryKeys).ToList(); 

Console.WriteLine("The number of differences is {0}", differences.Count); 
foreach (string diff in differences) 
{ 
    Console.WriteLine(diff); 
} 

И здесь без Linq:

var differences = new List<string>(); 

for (int i = 0; i < original.Count; i++) 
{ 
    bool found = false; 
    for (int j = 0; j < web.Count; j++) 
    { 
     if (original[i][0] == web[j][0]) 
     { 
      found = true; 
     } 
    } 

    if (!found) 
    { 
     differences.Add(original[i][0]); 
    } 
} 
0

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

Что может быть лучше, чтобы сделать это:

//Check for originals not introduced in web. 
     if(original.Count > web.Count) 
     { 

      for(int y = web.Count; y < original.Count; y++) 

      { 
       differences.Add(original[y][0]); 
      } 
     } 
//Check if Web has value, if not, everything else is done on the first for loop 
     if(web.Count > 0) 
     { 
      for(int i = 0; i < original.Count; i++) 
       { 
        if(!original[i][0].Equals(web[i][0])) 
         differences.Add(original[i][0]); 
       } 
     } 

Кроме того, выход в цикле, когда вам просто нужно один результат, длина рассогласования. Вы можете сделать это без цикла.

  Console.WriteLine("SIZE " + differences.Count); 

Это, конечно, чтобы сделать это своего рода проще, если вы не привыкли использовать операторы LINQ, но если вы можете сделать это с помощью LINQ, а затем всеми средствами, использовать LINQ, как это более эффективно.

0

Вы можете получить разницу с помощью Except метода расширения, как это:

var originalDic = original.ToDictionary(arr => arr.First()); 
var webDic = web.ToDictionary(arr => arr.First()); 
var differences = 
    originalDic 
    .Except(webDic, kvp => kvp.Key) 
    .Select(kvp => kvp.Value) 
    .ToList(); 

Хитрость здесь сначала преобразовать исходные и веб-списков в Dictionary используя первый элемент каждого массива как ключ, а затем выполнить Except.

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