Delete specific characters in string C#

Multi tool use
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()
);





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



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.

JbgQ,T8 9e20HVIwu1krKSSiCbmA8gh4eeSCl2daV
tTdUo 4udd5iBs6bqDDYDciy A4NY,T1JEH6

Popular posts from this blog

Delphi Android file open failure with API 26

.

Amasya