Delete specific characters in string C#

Multi tool use
Delete specific characters in string C#
I have a string that has all the available partition letters for allocation.
I want to delete each character (or drive letter) that is already in use from this string.
I have tried doing this:
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.
}
But notusedletters string always returns the initial value of allletters (ABCDEFGHIJKLMNOPQRSTUVWXYZ).
What's wrong with this code?
2 Answers
2
When you call a Replace
on allletters
a new string will be created. Replace
does not modify exists string.
To make your code work you should re-assign allletters
on each iteration:
Replace
allletters
Replace
allletters
allletters = allletters.Replace(....)
Or just use this single line linq query:
string allletters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string notusedletters = new string(
allletters.Except(
DriveInfo.GetDrives().Select(d => d.Name[0])
).ToArray());
It should be noted that Except does not guarantee that the order is preserved
I've checked this answer and it says that Except
preserves order. To make sure I've decompiled System.Core
Except
Please see implementation of Except
with my comments:
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
}
}
But to be 100% sure that behavior will not change in future you can use OrderBy
as @ckuri suggested in comment:
OrderBy
string notusedletters = new string(
allletters.Except(
DriveInfo.GetDrives().Select(d => d.Name[0])
)
.OrderBy(c => c) // explicit ordering
.ToArray()
);
Do not use notusedletters
or just keep the same string while using the replace
.
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);
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
It should be noted that Except does not guarantee that the order is preserved. There fore if the original order is required an OrderBy might be needed too.
– ckuri
Jun 30 at 20:55