2015-04-02 62 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 
相关问题