2012-08-22 53 views
2

你好我正在從XML文件填充的兩個dataGridView表中尋找唯一的字符串。我所做的代碼運行時沒有問題,但它無法檢測到我在其中一個表中更改字符串(使其唯一)。我的邏輯有什麼問題嗎?查找兩個數組中的唯一字符串C#

private void button5_Click(object sender, EventArgs e) 
    { 
     string[] column1 = new string[dataGridView1.Rows.Count]; 
     string[] column2 = new string[dataGridView2.Rows.Count]; 
     int unique = 0; 
     bool found = false; 
     for (int i = 0; i < dataGridView1.Rows.Count; i++) 
     { 
      column1[i] = Convert.ToString(dataGridView1.Rows[i].Cells[2].Value); 
     } 
     for (int i = 0; i < dataGridView2.Rows.Count; i++) 
     { 
      column2[i] = Convert.ToString(dataGridView2.Rows[i].Cells[2].Value); 
     } 
     for (int i = 0; i < column1.Length; i++) 
     { 
      for (int j = 0; j < column2.Length; j++) 
      { 
       if (column1[i] == column2[j]) 
       { 
        found = true; 
       } 
      } 
      if (found == false) 
      { 
       unique++; 
       found = false; 
      } 
     } 
     MessageBox.Show(unique + " unique strings found!"); 
    } 

最終的解決方案需要能夠返回包含唯一的字符串的細胞,使我可以將它們強調給用戶。非常感謝你的幫助!響應

array1.Except(array2).Concat(array2.Except(array1)) 

您的意見,您可以模擬一個完整的外部聯接兩個沒有加入,:

回答

0

你可以使用鏈接運營商,聯盟和鮮明的經營

var temp = column1.Union(column2); 
var result = temp.Distinct(); 
+0

我想我們可以跳過'Distinct'? – gotqn

2

易與LINQ並在輸出中查找空值。連接的任何一邊在另一邊都不匹配可以被認爲是唯一的。使用以下擴展名的加入:

public static class LinqEx 
{ 
    public static IEnumerable<TResult> 
     LeftOuterJoin<TOuter, TInner, TKey, TResult>(
      this IEnumerable<TOuter> outer, 
      IEnumerable<TInner> inner, 
      Func<TOuter, TKey> outerKeySelector, 
      Func<TInner, TKey> innerKeySelector, 
      Func<TOuter, TInner, TResult> resultSelector) 
    { 
     return outer 
      .GroupJoin(
       inner, 
       outerKeySelector, 
       innerKeySelector, 
       (a, b) => new 
       { 
        a, 
        b 
       }) 
      .SelectMany(
       x => x.b.DefaultIfEmpty(), 
       (x, b) => resultSelector(x.a, b)); 
    } 

    public static IEnumerable<TResult> 
     FullOuterJoin<TSet1, TSet2, TKey, TResult>(
      this IEnumerable<TSet1> set1, 
      IEnumerable<TSet2> set2, 
      Func<TSet1, TKey> set1Selector, 
      Func<TSet2, TKey> set2Selector, 
      Func<TSet1, TSet2, TResult> resultSelector) 
    { 
     var leftJoin = set1. 
      LeftOuterJoin(
       set2, 
       set1Selector, 
       set2Selector, 
       (s1, s2) => new {s1, s2}); 
     var rightJoin = set2 
      .LeftOuterJoin(
       set1, 
       set2Selector, 
       set1Selector, 
       (s2, s1) => new {s1, s2}); 
     return leftJoin.Union(rightJoin) 
      .Select(x => resultSelector(x.s1, x.s2)); 

    } 
} 

您可以創建,捕捉附加數據,如該項目的索引,它從何而來,以及外加入他們的匿名對象。結果兩邊的項目都會被濾除(因爲它們都存在於兩個集合中),所以結果集現在只包含對其中一個集合唯一的項目。

void Main() 
{ 
    var set1 = new[] {"a", "b", "c"}; 
    var set2 = new[] {"b", "c", "d", "d"}; 
    var annotatedSet1 = set1 
     .Select((item,index) => new {src = "set1", index, item}); 
    var annotatedSet2 = set2 
     .Select((item,index) => new {src = "set2", index, item}); 

    var uniques = annotatedSet1 
     .FullOuterJoin(
      annotatedSet2, 
      x => x.item, 
      x => x.item, 
      (s1, s2) => new {s1, s2}) 
     .Where(x => x.s1 == null || x.s2 == null) 
     .Select(x => x.s1 ?? x.s2); 
} 

這將產生的結果:

{src="set1", index=0, item="a"} 
{src="set2", index=2, item="d"} 
{src="set2", index=3, item="d"} 
+2

但是我能否檢索到唯一字符串所在的位置? –

+0

@OwenGarland你可以使用帶有索引的'select'重載來生成一個既包含索引又包含數據的匿名類,然後繼續使用此處顯示的方法。 – Servy

0

這裏有一個LINQ的方式與Enumerable.Except

var dg1Cell2 = dataGridView1 
    .Rows.Cast<DataGridViewRow>() 
    .Select(r => r.Cells[2].Value.ToString()); 
var dg2Cell2 = dataGridView1 
    .Rows.Cast<DataGridViewRow>() 
    .Select(r => r.Cells[2].Value.ToString()); 
var uniqueInDG1 = dg1Cell2.Except(dg2Cell2); 
var result = from r in dataGridView1.Rows.Cast<DataGridViewRow>() 
      join u in uniqueInDG1 on r.Cells[2].Value.ToString() equals u 
      select r; 

Except產生一組差異,所以纔有了第一序列中的唯一字符串保持。然後我將結果加入DataGridViewRows

它比看起來效率更高,因爲它全部都是懶惰地執行的,除了內部使用setjoin在linq-to-objects中也是very efficient

0

感謝您的回覆,但簡單的答案是,我沒有在正確的位置重置發現的值爲false。我很欣賞你的解決方案所付出的努力,但對於我的知識水平來說,它們都太複雜了。

這裏是調整後的代碼:

private void button5_Click(object sender, EventArgs e) 
    { 
     string[] column1 = new string[dataGridView1.Rows.Count]; 
     string[] column2 = new string[dataGridView2.Rows.Count]; 
     int unique = 0; 
     bool found = false; 
     for (int i = 0; i < dataGridView1.Rows.Count; i++) 
     { 
      column1[i] = Convert.ToString(dataGridView1.Rows[i].Cells[2].Value); 
     } 
     for (int i = 0; i < dataGridView2.Rows.Count; i++) 
     { 
      column2[i] = Convert.ToString(dataGridView2.Rows[i].Cells[2].Value); 
     } 
     for (int i = 0; i < column1.Length; i++) 
     { 
      for (int j = 0; j < column2.Length; j++) 
      { 
       if (column1[i] == column2[j]) 
       { 
        found = true; 
       } 
      } 
      if (found == false) 
      { 
       unique++; 
      } 
      found = false; 
     } 
     MessageBox.Show(unique + " unique strings found!");   
    } 
相關問題