Istället för .Split, .Replace("b", string.Empty);
Låt säga att jag har en array som ser ut så här:
Dim str As String() = "a,b,c,d".split(",")
Om jag nu vill ta bort ex. "b" ur arrayen hur gör jag då?
13 svar · 869 visningar · startad av Travoni
Låt säga att jag har en array som ser ut så här:
Dim str As String() = "a,b,c,d".split(",")
Om jag nu vill ta bort ex. "b" ur arrayen hur gör jag då?
Istället för .Split, .Replace("b", string.Empty);
Då blir det ett komma över...
.Replace("b", string.Empty).Replace(",,",",")
Kanske... Känns som en fullösning men det kanske funkar.
Vad tror du om något sådant hära:
private bool isInArray(string searchFor, string CommaString)
{
string[] tmpStr = CommaString.Split(",");
for (int i = 0; i <= tmpStr.Length - 1; i++) {
if (searchFor == tmpStr(i))
return true;
}
return false;
}
private string removeFromString(string searchFor, string CommaString)
{
return CommaString.Replace(searchFor, string.Empty).Replace(",,", ",");
}
private string addToString(string strToAdd, string CommaString)
{
if (!isInArray(strToAdd, CommaString)) {
return string.Concat(CommaString, ",", strToAdd);
}
else {
return CommaString;
}
}
Ändra inte i källsträngen, det är katastrofalt fult. Finns många sätt att göra det på.
List.Remove:
List<string> strings = new List<string>("a,b,c,d".Split(","));
strings.Remove(s => s == "b");
Extension på IEnumerable:
public static IEnumerable<T> AllExcept<T>(this IEnumerable<T> self, T except)
{
foreach (T value in self) if (value != except) yield return value;
}
...
IEnumerable<string> values = "a,b,c,d".Split(",").AllExcept("b");
Eller med Linq-extensions (otestad):
"a,b,c,d".Split(",").Select(s => s != "b");
Nickemannen skrev:
Istället för .Split, .Replace("b", string.Empty);
.Replace("b,", string.Empty)
Nickemannen skrev:
.Replace("b,", string.Empty)
Den där är ju inge kul om du skall ta bort sista elementet, där saknar vi en slut ",". Spangos exempel känns mer rätt.
Travoni skrev:
Det låter bra, men hur menar du?
Det är vansinne att ändra på ett serialiserat värde. Koden blir lättare att läsa, skriva, ändra och felsöka (vilket redan bevisats av den här tråden, med alla ändringar som gjorts på replacevarianterna) om man gör filtreringen på det deserialiserade värdet (dvs arrayen) än om man gör ändringarna på den serialiserade representationen (dvs den kommaseparerade strängen). Ändrar du på hur arrayen representeras som en sträng behöver du bara ändra på två ställen (serialisering/deserialisering) istället för på tre (de förra två + filtreringsfunktionen). Inte osannolikt blir det snabbare också, även om det bara är ett andrahandsargument emot. (Det effektivaste torde vara att göra filtrering och de/serialisering samtidigt, men det känns lite overkill här.)
Ok, jag hajjar.
Jag kan beskriva mitt "problem" ifrån början.
Jag har en xml-fil där jag lagrar värden på detta sätt
<department name="News">
<item name="canRead" value="Admin,Users,Moderators" />
<item name="canWrite" value="Admin,Moderators" />
</department>
Nu vill jag lista det rättigheter som ex. Admin har i en checkboxlist varpå en checkbox skall vara ikryssad ifall Admin har rättigheter på respektive post.
När jag uppdaterar så skall värdet returneras med den nya kommaseparerade listan.
Det kan hända att detta är ett dumt system men annars så blir det så många poster i xml-filen. Plus att det blir "fel" när man ex tar bort roller.
<department name="News">
<item name="AdminCanRead" value="True" />
<item name="AdminCanWrite" value="True" />
<item name="UsersCanRead" value="True" />
<item name="UsersCanWrite" value="False" />
<item name="ModeratorsCanRead" value="True" />
<item name="ModeratorsCanWrite" value="True" />
</department>
Alt:
<group name="Admin">
<item name="CanReadNews" value="True" />
<item name="CanWriteNews" value="True" />
</group>
<group name="Moderators">
<item name="CanReadNews" value="True" />
<item name="CanWriteNews" value="True" />
</group>
<group name="Users">
<item name="CanReadNews" value="True" />
<item name="CanWriteNews" value="False" />
</group>
Tips emottages gärna hur jag skall lösa detta.
Tja, det är pest eller kolera egentligen när man vill hantera såna här strukturer med XML, men jag skulle använda en enum med FlagsAttribute så att man kan kombinera värden:
[Flags]
enum Permission { None = 0, Read = 1, Write = 2 }
Sen kan du ha en XML-struktur som:
<department name="News">
<permission for="Admin" allows="Read,Write" />
<permission for="Moderators" allows="Read,Write" />
<permission for="Users" allows="Read" />
</department>
Därefter kan du använda Enum.Parse för att göra om det till enum-värden, och kolla med bitmaskoperationer:
Permission p = (Permission)Enum.Parse(typeof(Permission), "Read,Write");
Console.WriteLine("Permission: {0}", p.ToString());
if ((p & Permission.Read) == Permission.Read) Console.WriteLine("Can read");
if ((p & Permission.Write) == Permission.Write) Console.WriteLine("Can write");
Console.WriteLine("Disabling write permission...");
p &= ~Permission.Write; // stäng av write
Console.WriteLine("Permission: {0}", p.ToString());
if ((p & Permission.Read) == Permission.Read) Console.WriteLine("Can read");
if ((p & Permission.Write) == Permission.Write) Console.WriteLine("Can write");
Console.WriteLine("Enabling write permission...");
p |= Permission.Write; // slå på write
Console.WriteLine("Permission: {0}", p.ToString());
if ((p & Permission.Read) == Permission.Read) Console.WriteLine("Can read");
if ((p & Permission.Write) == Permission.Write) Console.WriteLine("Can write");
Det kan se lite mysko ut men är väldigt behändigt och effektivt och hyggligt typsäkert. Minnesregler (p är en variabel med kombinationer av flaggor, x är en flagga):
Har noll koll på hur bitvisa operationer ser ut i VB.Net är jag dock rädd :)
Har du sen en klass för en grupps rättigheter på en avdelning skulle den alltså kunna se ut som:
public class DepartmentPermission
{
public Group Group { get; set; }
public Department Department { get; set; }
public Permission Permissions { get; set; }
public bool CanRead
{
get { return GetPermission(Permission.Read); }
set { SetPermission(Permission.Read, value); }
}
public bool CanWrite
{
get { return GetPermission(Permission.Write); }
set { SetPermission(Permission.Write, value); }
}
private bool GetPermission(Permission p) { return (Permissions & p) == p; }
private void SetPermission(Permission p, bool on)
{
if (on) Permissions |= p;
else Permissions &= ~p;
}
}
Tack för att du tar dig tid Spango! :)
Det är kanske en databas jag skall använda ändå.
Det är lite ju lite lättare att hantera, eller vad tror du?
Travoni skrev:
Tack för att du tar dig tid Spango! :)
Det är kanske en databas jag skall använda ändå.
Det är lite ju lite lättare att hantera, eller vad tror du?
Tja, det vore kanske enklare om du redan har en databas :) XML är ju sådär när det gäller att representera många-till-många-relationer.