2015-04-02 66 views
1

考慮下面的代碼複製從一個列表中的所有配套項目到另一個

List<string> one = new List<string>(); 
List<string> two = new List<string>(); 

列出一個包含3串

Test 1 
Test 1 
Test 2 

我怎麼會串Test 1匹配,並把每個匹配字符串List two和從列表中刪除匹配的字符串,所以它只剩下Test 2字符串

這就是我到目前爲止

if (one.Any(str => str.Contains("Test 1"))) 
{ 
    //What to do here 
} 

如果我使用AddRange()它增加了整個列表一個列出兩位

+5

你是什麼意思:*我怎麼會匹配字符串測試1,把每個匹配List 2中的字符串;你究竟是什麼意思*匹配字符串測試1 * – 2015-04-02 11:58:48

+0

你在尋找'Intersect' http://www.dotnetperls.com/intersect – 2015-04-02 12:00:12

+0

我建議你試着看看'foreach'循環並讓它循環每個項目在列表1中,如果它在列表1中找到某些東西,將它放在列表2中,並將它從列表1中移除,可以使用'indexOf'和'removeAt'來完成。我想你可以弄清楚如何由你自己使用它們。 – maam27 2015-04-02 12:00:18

回答

1

所以,你想從one刪除所有「測試1」並將其添加到two。所以實際上你想把它們從一個列表轉移到另一個列表?

string toFind = "Test 1"; 
var foundStrings = one.Where(s => s == toFind); 
if(foundStrings.Any()) 
{ 
    two.AddRange(foundStrings); 
    one.RemoveAll(s => s == toFind); 
} 

這裏有一個非LINQ版本,更有效,但也許並不爲可讀:

// backwards loop because you're going to remove items via index 
for (int i = one.Count - 1; i >= 0; i--) 
{ 
    string s1 = one[i]; 
    if (s1 == toFind) 
    { 
     two.Add(toFind); 
     one.RemoveAt(i); 
    } 
} 
+0

非常感謝您的幫助 – Izzy 2015-04-02 14:12:05

4

任務也使用LINQ如下解決。

var NewOne = one.Where(iString => iString == "Test1") 
var NewTwo = one.Except(NewOne); 

one = NewOne.ToList(); 
two = NewTwo.ToList(); 
+1

「除外」的一個非常重要的副作用是它不僅刪除「Test1」,而且還刪除任何重複。這是因爲'Except'是一個*設置操作*。因此,如果原始集合由'[Test1,Test2,Test2]'組成,則結果將是'[Test2]' – dcastro 2015-04-02 12:24:09

+1

他想從'one'中刪除所有「Test1」並將它們添加到'two'。所以實際上他想轉移他們。 – 2015-04-02 12:39:37

0

作爲非LINQ解決方案的例子,好像這工作得很好:

List<string> one = new List<string>(new[] {"Test 1", "Test 1", "Test 2"}); 
List<string> two = new List<string>(); 
var toRemove = new List<string>(); 

foreach (var value in one) 
{ 
    if(value.Equals("Test 1")) 
    { 
     toRemove.Add(value); 
     two.Add(value); 
    } 
} 

foreach (var value in toRemove) 
{ 
    one.Remove(value); 
} 
+2

請解釋投票。 – 2015-04-02 12:02:13

+0

我完全意識到這不是「最光滑」的答案,但仍......它是無效的嗎? – 2015-04-02 12:19:08

+1

我必須在這一個上使用@ roryap。除了命名約定之外,它仍然是獲得OP後續結果的解決方案。 – 2015-04-02 12:42:38

0

嘗試

 List<string> two = (from i in one 
          where i.Contains("Test 1") 
          select i).ToList(); 

     one = one.Except(two).ToList(); 

或者更簡潔:

List<string> two = one.Where(i => i.Contains("Test 1")).ToList(); 
one = one.Except(two).ToList(); 
1

如果你想檢查這個字符串:

string match = "Test1"; 

然後使用此:

two.AddRange(one.Where(x => x == match)); 

從列表one所有匹配的記錄放到列表two

然後,使用這樣的:

one.RemoveAll(x => x == match); 

從列表中刪除one所有匹配的記錄。

0

我會做這樣的事情:

//set string to match 
string match = "Test 1"; 
//check each item in the list 
for(int i =0; i<one.Count;i++) 
    { 
    if (one[i].Equals(match)) //see if it matches 
     { 
     int index = one.IndexOf(match);//get index of the matching item 
     one.RemoveAt(index);//remove the item 
     two.Add(match);//add the item to the other list 
     } 
    } 
1

這個怎麼樣?

two.AddRange(one.FindAll(x => x.Contains("Test 1"))); 
one.RemoveAll(x => two.Contains(x)); 

以下代碼

List<string> one = new List<string>(); 
List<string> two = new List<string>(); 

one.Add("Test 1"); 
one.Add("Test 1"); 
one.Add("Test 2"); 

two.AddRange(one.FindAll(x => x.Contains("Test 1"))); 
one.RemoveAll(x => two.Contains(x)); 

Console.WriteLine("ONE:"); 
foreach (string s in one) 
{ 
    Console.WriteLine(s); 
} 
Console.WriteLine("TWO:"); 
foreach (string s in two) 
{ 
    Console.WriteLine(s); 
} 
Console.ReadLine(); 

應導致

ONE: 
Test 2 
TWO: 
Test 1 
Test 1 
0

嘗試這種情況:

two = one.FindAll(x => x.Contains("Test 1"); 
one.RemoveAll(x => x.Contains("Test 1"); 
+1

考慮添加一個解釋,說明這個代碼如何比現有答案更好地解決問題。一般來說,解釋得分高於沒有得分的答案。 – 2015-04-02 12:57:08

0

Sequences具有用於此特定使用情況下,Sequence<T>.Partition的方法。

var lists = one.AsSequence().Partition(x => x == "Test1"); 

var withTestOne = lists.Item1; 
var withoutTestOne = lists.Item2; 
0

另一種選擇是使用GROUPBY子句。下面,我提供了一個演示。我已經包含了檢索特定項目的方法(例如,測試1)以及移動所有現有重複項目的方法。 (更多詳細的代碼註釋。)

class Program 
{ 
    static List<string> _firstList; 
    static List<string> _secondList; 

    static void Main(string[] args) 
    { 
     // Initialize test values 
     Setup(); 

     // Display whats presenting in list 1. 
     Display(); 

     // Fill list 2 with all items in list 1 where the item is a value and remove the item 
     // from list 1. 
     FillListTwoWithSpecificValue("Test 1"); 

     /* Uncomment the line below if you want to populate list 2 with all duplicate items 
        while removing them from list 1.*/ 
     // FillListWithAllDuplicates(); 

     // Display the results after changes to list 1 and list 2 have been applied. 
     Display(); 

     Console.ReadLine(); 
    } 

    // Bonus method. Fills list 2 with any instance of a duplicate item pre-existing in list 1 while removing the item from the list. 
    static void FillListTwoWithAllDuplicates() 
    { 
     // Group the items in the first list 
     var duplicates = _firstList 
      .GroupBy(item => item) 
      .Where(g => g.Count() > 1) 
      .SelectMany(grp => grp); 

     // Iterate through each duplicate in the group of duplicate items and add them to the second list and remove it from the first. 
     foreach (var duplicate in duplicates) 
     { 
      _secondList.Add(duplicate); 

      // Remove all instances of the duplicate value from the first list. 
      _firstList.RemoveAll(item => item == duplicate); 
     } 
    } 

    // Fill list 2 with any instance of a value provided as a parameter (eg. Test 1) and remove the same value from list 1. 
    static void FillListTwoWithSpecificValue(string value) 
    { 
     // Group the items in the first list, and select a group according to the value provided. 
     var duplicates = _firstList 
      .GroupBy(item => item) 
      .SelectMany(grp => grp.Where(item => item == value)); 

     // Iterate through each duplicate in the group of duplicate items and add them to the second list and remove it from the first. 
     foreach (string duplicate in duplicates) 
     { 
      _secondList.Add(duplicate); 

      // Remove all instances of the duplicate value from the first list. 
      _firstList.RemoveAll(item => item == duplicate); 
     } 
    } 

    // Simply a method to initialize the lists with dummy data. This is only meant to keep the code organized. 
    static void Setup() 
    { 
     // Initialize lists 
     _firstList = new List<string>() 
     { 
      "Test 1", 
      "Test 1", 
      "Test 2", 
      "Test 3", 
      "Test 3", 
      "Test 4", 
      "Test 4", 
      "Test 5", 
      "Test 6", 
     }; 

     _secondList = new List<string>(); 
    } 

    // Simply a method to display the output to the console for the purpose of demonstration. This is only meant to keep the code organized. 
    static void Display() 
    { 
     // Checking to see if the second list has been populated. If not, lets just display what's in list 1 
     // since no changes have been made. 
     if (_secondList.Count == 0) 
     { 
      // Display the list 1 values for comparison. 
      Console.WriteLine("Items contained in list 1 before items moved to list 2:\n------------------------------------"); 
      foreach (var item in _firstList) 
      { 
       Console.WriteLine(item); 
      } 
     } 
     else 
     { 
      Console.WriteLine("\nItems now in list 1 after duplicates being removed:\n------------------------------------"); 
      foreach (var item in _firstList) 
      { 
       Console.WriteLine(item); 
      } 

      Console.WriteLine("\nItems now in list 2:\n------------------------------------"); 
      foreach (var item in _secondList) 
      { 
       Console.WriteLine(item); 
      } 
     } 
    } 
} 

結果將是以下幾點:

Items contained in list 1 before items moved to list 2: 
------------------------------------ 
Test 1 
Test 1 
Test 2 
Test 3 
Test 3 
Test 4 
Test 4 
Test 5 
Test 6 

Items now in list 1 after duplicates being removed: 
------------------------------------ 
Test 2 
Test 3 
Test 3 
Test 4 
Test 4 
Test 5 
Test 6 

Items now in list 2: 
------------------------------------ 
Test 1 
Test 1 
相關問題