我有一个字符串,其中包含用于分配的所有可用分区字母。
我想从此字符串中删除已在使用的每个字符(或驱动器号)。
我试过这样做:
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 字符串总是返回 allletters 的初始值 (ABCDEFGHIJKLMNOPQRSTUVWXYZ)。
这段代码有什么问题?
当您调用 a 时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());
需要注意的是,Except不保证订单被保留
我已经检查了这个答案,它说可以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()
);
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句