【问题标题】:Delete specific characters in string C#删除字符串 C# 中的特定字符
【发布时间】:2018-06-30 08:46:37
【问题描述】:

我有一个字符串,其中包含所有可用的分区字母进行分配。

我想从这个字符串中删除每个已经在使用的字符(或驱动器号)。

我试过这样做:

string allletters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
DriveInfo[] d = DriveInfo.GetDrives();


string notusedletters = string.Empty;

foreach (DriveInfo drive in AllDrives)
{
    string driveLetterOnly = (drive.Name).Replace(@":\", ""); // remove ":\" characters from the drive letter
    notusedletters = allletters.Replace(driveLetterOnly, ""); // remove driveLetterOnly from the allletters string.
}

但 notusedletters 字符串总是返回所有字母的初始值 (ABCDEFGHIJKLMNOPQRSTUVWXYZ)。

这段代码有什么问题?

【问题讨论】:

    标签: c# string character


    【解决方案1】:

    当您在allletters 上调用Replace 时,将创建一个新字符串。 Replace 不修改存在的字符串。 为了使您的代码正常工作,您应该在每次迭代时重新分配 allletters

    allletters = allletters.Replace(....)
    

    或者只使用这个单行 linq 查询:

    string allletters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    string notusedletters = new string(
      allletters.Except(
        DriveInfo.GetDrives().Select(d => d.Name[0])
      ).ToArray());
    


    来自 cmets:

    需要注意的是,Except不保证订单被保留

    我检查了this 的答案,它说Except 保留了顺序。为了确保我已经反编译 System.Core

    请使用我的 cmets 查看 Except 的实现:

    public static IEnumerable<TSource> Except<TSource>(
      this IEnumerable<TSource> first,
      IEnumerable<TSource> second)
    {
      // I removed a null checks
      return Enumerable.ExceptIterator<TSource>(first, second,
        (IEqualityComparer<TSource>) null);
    }
    
    private static IEnumerable<TSource> ExceptIterator<TSource>(
      IEnumerable<TSource> first,
      IEnumerable<TSource> second,
      IEqualityComparer<TSource> comparer)
    {
      Set<TSource> set = new Set<TSource>(comparer);
      foreach (TSource source in second)
        set.Add(source);
      foreach (TSource source in first)
      {
        if (set.Add(source))
          yield return source; // elements will be yielded in same order
                               // as they appear in first sequence
      }
    }
    

    但要 100% 确保将来行为不会改变,您可以使用 @ckuri 在评论中建议的 OrderBy

    string notusedletters = new string(
        allletters.Except(
          DriveInfo.GetDrives().Select(d => d.Name[0])
        )
        .OrderBy(c => c) // explicit ordering
        .ToArray()
      ); 
    

    【讨论】:

    • 需要注意的是,Except不保证订单被保留。因此,如果需要原始订单,也可能需要 OrderBy。
    【解决方案2】:

    不要使用notusedletters 或在使用replace 时只保留相同的字符串。

    string allletters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    DriveInfo[] d = DriveInfo.GetDrives();
    
    foreach (DriveInfo drive in d)
    {
        string driveLetterOnly = (drive.Name).Replace(@":\", ""); // remove ":\" characters from the drive letter
        allletters = allletters.Replace(driveLetterOnly, ""); // remove driveLetterOnly from the allletters string.
    }
    Console.WriteLine(allletters);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      • 2021-01-25
      • 1970-01-01
      • 2019-11-09
      • 1970-01-01
      • 2013-12-13
      相关资源
      最近更新 更多