2017-01-05 17 views
0

我想从列表避免与鲜明的所有重复从列表中写入该文件除特定值

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

我用不同的,以避免重复写入文件前执行

IEnumerable<string> sepStr = List.Distinct(); 

foreach (string StrExtractToFile in sepStr) 
{      
    using (StreamWriter sw = File.AppendText(doc.txt)) 
      sw.WriteLine(StrExtractToFile); 
} 

但我想避免所有重复,除了单词“边界”。进入文件如果存在于List中,则为“border”。必须通过重复传入文件,必须避免其他重复。

我不确定什么是正确或正确的说更好的方法来做到这一点。我不知道,如果String.Contains Method是这种情况的方式

+0

没有关系吗? – taquion

+0

@taquion你好,是的订单很重要。清单一直更新,但订单必须保存。并且我从列表到文件以字符串的形式写入字符串,并且从文件到列表的方式也是一样。 – nikorio

回答

2

你可以让你自定义的IEqualityComparer<>以获得所需的行为:

class CustomComparer : EqualityComparer<string> 
{ 
    public override bool Equals(string x, string y) 
    { 
     if (x == "border" || y == "border") return false; 
     return Default.Equals(x, y); 
    } 

    public override int GetHashCode(string obj) 
    { 
     return obj.GetHashCode(); 
    } 
} 

然后,调用Distinct超载经过比较器的一个实例:

SplitContList.Distinct(new CustomComparer()); 

或者,你可以这样做:

SplitContList.Select((w, i) => new { w, key = w == "border" ? i : 0 }) 
      .Distinct() 
      .Select(x => x.w); 
+0

我尝试了两种方式,但它删除了写入文件的边框,不知道我是否做错了什么。我已编辑我的问题更清晰 – nikorio

+0

@nikorio:所以你希望重复出现在所有?如果列表是'a,border,a,b,c,border,c,d',那么结果列表应该是什么? –

0

您可以使用LINQ做到这一点,但我只想用一个快速循环...

List<String> Str = new List<String>(); 
foreach (string s in SplitContList) 
{ 
    if (s == "Border" || !Str.Contains(s)) 
     Str.Add(s); 
} 

此字符串添加到列表如果它是“边框”或者它不在列表中。

+0

嗨,我有编辑问题,因为它不够清楚,没有给出的代码适用于我 – nikorio

+0

此循环仅过滤出重复的字符串。您可以在调用Str.Add(s);的同时执行您的stringwriter.append(或其他任何您想要执行的操作)。 –

0
void Main() 
{ 
    var items = new List<String>{"Brett", "James", "James", "Border", "Border", "John"}; 
    var distincts = items.Where(x => x != "Border").Distinct().ToList(); 
    var borders = items.Where(x => x == "Border").ToList(); 
    distincts.Concat(borders).ToList().ForEach(x => Console.WriteLine(x)); 
} 
+0

你好,与其他解决方案相同的结果,我编辑了我的问题,所以也许它不清楚,请检查我的编辑 – nikorio

+0

你说:'但我想避免所有重复,除了单词“border”。进入文件如果存在于List中,则为“border”。必须通过重复传入文件,必须避免其他重复。“这就是这样做的。它删除重复项,除非它们是模拟中的单词边界。除非你提供更多细节,否则我不知道你真正想要什么。 – djangojazz

0

也许有一个优雅的LINQ的解决方案,我没有想到的,但经典的解决方案是不是很难想到的任何

List<string> results = new List<string>(); 
foreach(var s in SplitContList) 
{ 
    if(!results.Contains(s) || s == "border.") 
    { 
     results.Add(s); 
    } 
} 
+0

@ Paul Kertscher你好,我编辑我的问题,似乎不是很清楚,因为没有给出的解决方案不适合我的方式 – nikorio

0

我去@Elemental皮特的回答只是一个改变

var SplitContList = new List<string>(); 
     var Str = new List<String>(); 
     foreach (var s in SplitContList) 
      if (s.Equals("border",StringComparison.InvariantCultureIgnoreCase)|| !Str.Contains(s)) 
       Str.Add(s); 

万一你没有关系的情况下

+0

@djangojazz答案也可以,但列举了两次列表,而这(元素皮特的)回答只是一次 – taquion

+0

你好,我编辑我的问题,因为它不清楚,所以似乎没有任何工作,因为我需要,或者我做错了什么,只是检查 – nikorio

0
var filteredList = SplitContList 
         .Where(c => c != "border") 
         .GroupBy(v => v) 
         .Select(group => group.First()) 
         .Concat(SplitContList.Where(c => c == "border")).ToList(); 
+0

我编辑的问题,因为它似乎是不清楚。不确定,但没有任何工作从给定的解决方案正确的形式我 – nikorio

+0

@nikorio如果解决方案不起作用downvote,请。 – wp78de

+0

你可以尝试描述更多细节。 – aircraft

0

我会去与另一个集合,它包含已经附加的字符串和检查循环。

List<string> List = new List<string>(); 
HashSet<string> alreadyUsed = new HashSet<string>(); 
using (StreamWriter sw = File.AppendText(doc.txt)) 
{ 
    foreach (string StrExtractToFile in List) 
    { 
     if (StrExtractToFile == "border" || !alreadyUsed.Contains(StrExtractToFile)) 
     { 
      alreadyUsed.Add(StrExtractToFile); 
      sw.WriteLine(StrExtractToFile); 
     } 
    } 
}