Применить маску к строке
У меня есть флаг enumeration (int) mask, и мне нужно преобразовать его в строку, представляющую день недели.
скажем, что это FULL строка и произвольная маска
strFullWeek = "MTWtFSs"
strWeekMask = "0100110"
-----------------------
strResult = "-T--FS-"
Какой способ вы могли бы получить strResult из целых недель и строк маски?
UPDATE
это мой "весь контекст" (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)
Ответы
Ответ 1
Там достаточно аккуратный способ LINQ:
var chars = strFullWeek.Zip(strWeekMask, (day, mask) => mask == '1' ? day : '-'))
.ToArray();
string text = new string(chars);
Это было бы не очень эффективно, но это может быть достаточно...
EDIT: Хорошо, если вы довольны кодом С# для версии enum
// 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);
Ответ 2
В моем быстром решении используется 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
: '-')));
Ответ 4
Вот альтернатива, если вы ищете читаемость:
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);
Ответ 5
Я опаздываю на вечеринку; но я хотел попробовать. Здесь мой менее классный подход LINQ:
var result = new string(strFullWeek.Select((letter, index)
=> strWeekMask[index] == '1' ? letter : '-').ToArray());
Ответ 6
Если вы хотите напрямую использовать перечисление, вы можете сделать это примерно так:
[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