删除字符串C#

时间:2018-06-30 08:46:38

标签: c# string character

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

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

我尝试这样做:

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)。

此代码有什么问题?

2 个答案:

答案 0 :(得分:2)

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

allletters = allletters.Replace(....)

或仅使用此单行linq查询:

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


来自评论:

  

应注意,除不保证保留订单外,

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

请在我的评论中查看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%确保以后的行为不会改变,您可以使用OrderBy,如@ckuri在注释中建议的那样:

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

答案 1 :(得分:1)

在使用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);