将“掩码”应用于字符串

14
我有一个标志枚举(int)掩码,我需要将它转换为表示星期几的字符串。假设这是完整的字符串和任意的掩码。
strFullWeek = "MTWtFSs"
strWeekMask = "0100110"
-----------------------
strResult   = "-T--FS-"

你会提出什么方法来从完整的星期和掩码字符串中获取 strResult?

更新

这是我的“全部上下文”(VB.NET)

<Flags()> Public Enum Week
  Monday = 1
  Tuesday = 2
  Wednesday = 4
  Thursday = 8
  Friday = 16
  Saturday = 32
  Sunday = 64
End Enum

Dim mondayOrSunday = Week.Monday Or Week.Sunday
Dim strDays = "MTWtFSs"

Dim strMondayOrSundayBinary = Convert.ToString(
  mondayOrSunday, 2).PadRight(7, CChar("0"))

Dim charMondayOrSunday = strDays.Zip(
  strMondayOrSundayBinary,
  Function(day, mask) If(mask = CChar("1"), day, CChar("-"))).ToArray()

Dim strMondayOrSunday = New String(charMondayOrSunday)

Console.WriteLine("{0} I see as {1}",
                  mondayOrSunday,
                  strMondayOrSunday)

你最关心的是什么?速度,可维护性/可读性,还是代码行数最少? - Steven Doggart
6个回答

20

有一个相当简洁的LINQ方法:

var chars = strFullWeek.Zip(strWeekMask, (day, mask) => mask == '1' ? day : '-'))
                       .ToArray();
string text = new string(chars);

虽然这样做效率不高,但可能已经足够了……

编辑:好的,假设您对枚举版本的C#代码感到满意。

// TODO: Rename "Week" to comply with .NET naming conventions
Week mask = Week.Monday | Week.Sunday;
var chars = strFullWeek.Select((value, index) => (int) mask & (1 << index) != 0) 
                                                 ? value : '-')
                       .ToArray();
string text = new string(chars);

为了获取 strWeekMask,我使用了 Convert.ToString(myEnum, 2)...也许我可以直接使用枚举? - serhio
@serhio:很可能是这样。给我们完整的上下文,我们就能给你一个更好的答案。 - Jon Skeet
我有一个标志枚举,代表一周中的每一天。任务是将其转换为可读的字符串(“-T--FS-”)。 - serhio
@serhio:不要“告诉”我们上下文-请将枚举类型编辑到您的问题中。展示您所拥有的“原始”信息。很可能有更好的方法来解决这个问题。 - Jon Skeet

5

我的快速解决方案使用了StringBuilder。它允许您原地操作字符串。但除非您调用此代码一百万次,否则与LINQ解决方案相比,您不会注意到任何速度差异。

string strFullWeek = "MTWtFSs";
string strWeekMask = "0100110";

var sb = new StringBuilder(strFullWeek);
for (int i = 0; i < strWeekMask.Length; i++) {
    if (strWeekMask[i] == '0') {
        sb[i] = '-';
    }
}
string result = sb.ToString();

3

请看下文:

var strFullWeek = "MTWtFSs";
var strWeekMask = "0100110";

var strFullWeekArray = strFullWeek.ToList();
var strWeekMaskArray = strWeekMask.ToList();

Console.WriteLine(string.Join(
    string.Empty,
    strFullWeek.Select(c => (strWeekMaskArray[strFullWeekArray.IndexOf(c)] == '1')
        ? c
        : '-')));

2
如果你想要更易读的选项,这里有一个替代方案:
string fullWeek = "MTWtFSs";
string weekMask = "0100110";

const char blankChar = '-';

int totalChars = fullWeek.Length;

StringBuilder result = new StringBuilder();

for (int index = 0; index < totalChars; index++)
{
    if (weekMask[index] == '1')
    {
        result.Append(fullWeek[index]);
    }
    else
    {
        result.Append(blankChar);
    }
}

Console.WriteLine(result);

1

虽然我来晚了,但是我想尝试一下。这是我的非常规 LINQ 方法:

var result = new string(strFullWeek.Select((letter, index) 
                         => strWeekMask[index] == '1' ? letter : '-').ToArray());

1
如果您想直接使用枚举,可以像这样操作:
[Flags()]
enum Week
{
    Monday = 1,
    Tuesday = 2,
    Wednesday = 4,
    Thursday = 8,
    Friday = 16,
    Saturday = 32,
    Sunday = 64
}

const string strFullWeek = "MTWtFSs";

string GetMaskedWeek(Week days)
{
    char[] result = new char[strFullWeek.Length];
    for (int i = 0; i < strFullWeek.Length; i++)
    {
        if ((((int)days >> i) & 1) != 0)
            result[i] = strFullWeek.ToCharArray(i, 1)[0];
        else
            result[i] = '-';
    }
    return new string(result);
}

或者,在VB.NET中:

<Flags()> Public Enum Week
    Monday = 1
    Tuesday = 2
    Wednesday = 4
    Thursday = 8
    Friday = 16
    Saturday = 32
    Sunday = 64
End Enum

Dim strFullWeek As String = "MTWtFSs"

Private Function GetMaskedWeek(ByVal days As Week) As String
    Dim result(strFullWeek.Length) As Char
    For i As Integer = 0 To strFullWeek.Length - 1
        If ((days >> i) And 1) <> 0 Then
            result(i) = strFullWeek.ToCharArray(i, 1)(0)
        Else
            result(i) = "-"c
        End If
    Next
    Return New String(result)
End Function

这实际上是我最初的代码,但我将其更新以匹配问题中的枚举,其中星期四为16 :) - Steven Doggart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接