Usuń ostatni znak ciągu

259

Pobieram wiele informacji z listy połączonej z bazą danych i chcę utworzyć ciąg grup dla kogoś, kto jest podłączony do strony internetowej.

Używam tego do testowania, ale nie jest to dynamiczne, więc jest naprawdę złe:

string strgroupids = "6";

Chcę tego teraz użyć. Ale zwrócony ciąg znaków jest podobny1,2,3,4,5,

groupIds.ForEach((g) =>
{
    strgroupids = strgroupids  + g.ToString() + ",";
    strgroupids.TrimEnd(',');
});

strgroupids.TrimEnd(new char[] { ',' });

Chcę usunąć ,po, 5ale zdecydowanie nie działa.

Kiwimoisi
źródło
9
Rozwiązaniem bezpośredniego problemu jest, strgroupids = strgroupids.TrimEnd(new char[] { ',' });ale poniżej są lepsze pomysły.
Henk Holterman

Odpowiedzi:

613
strgroupids = strgroupids.Remove(strgroupids.Length - 1);

MSDN:

String.Remove (Int32):

Usuwa wszystkie znaki z tego ciągu, zaczynając od określonej pozycji i kontynuując do ostatniej pozycji

sll
źródło
1
Idealny do usunięcia ostatniego znaku, jeśli chcesz usunąć ostatni znak. W przypadku pytania OP problem nie powinien istnieć, jeśli nie utworzysz końcowego znaku. Sprawdź @ Øyvind Bråthen rozwiązanie, jeśli jesteś na łodzi OP.
aloisdg przenosi się do codidact.com,
86

Co powiesz na robienie tego w ten sposób?

strgroupids = string.Join( ",", groupIds );

Wiele czystsze.

Będzie dołączyć wszystkie elementy wewnątrz groupIdsz ','pomiędzy siebie, ale to nie będzie umieścić ','na końcu.

Øyvind Bråthen
źródło
4
Tylko w C # 4.0. W C # 3.5 będziesz musiał przekonwertować groupIds na tablicę.
xanatos
3
Ten naprawi problem OP.
aloisdg przenosi się do codidact.com,
29

Ciągi w c # są niezmienne. Kiedy w kodzie zrobić strgroupids.TrimEnd(',');lub ciąg nie jest modyfikowany .strgroupids.TrimEnd(new char[] { ',' });strgroupids

Zamiast tego musisz zrobić coś takiego strgroupids = strgroupids.TrimEnd(',');.

Aby cytować stąd :

Ciągi są niezmienne - zawartość obiektu łańcuchowego nie może zostać zmieniona po utworzeniu obiektu, chociaż składnia sprawia, że ​​wygląda to tak, jakbyś mógł to zrobić. Na przykład, gdy piszesz ten kod, kompilator faktycznie tworzy nowy obiekt łańcuchowy do przechowywania nowej sekwencji znaków, a ten nowy obiekt jest przypisywany do b. Ciąg „h” kwalifikuje się wówczas do wyrzucania elementów bezużytecznych.

Andy Johnson
źródło
11

Dodaj metodę rozszerzenia.

public static string RemoveLast(this string text, string character)
{
    if(text.Length < 1) return text;
    return text.Remove(text.ToString().LastIndexOf(character), character.Length);
}

następnie użyj:

yourString.RemoveLast(",");
nznoor
źródło
Podstawowa idea tworzenia metody rozszerzenia jest dobra. Jednak IMHO, zastosowana tutaj metoda jest nadmierna, w tym zastosowaniu. OP wiedział, że znak, którego chciał, znajduje się na końcu łańcucha, więc nie ma powodu, aby kosztować szukanie tego łańcucha za pośrednictwem LastIndexOf. Wystarczy przyjąć przyjętą odpowiedź i uczynić z niej metodę rozszerzenia. Lub uogólnij tę odpowiedź, przekazując int nliczbę znaków do usunięcia na końcu. Po drugie, testujesz zerową długość, ale to nie eliminuje wszystkich możliwych wyjątków. Lepiej byłoby zrobić int index = ..LastIndexOf.., to if (index >= 0).
ToolmakerSteve
Po trzecie, parametr string characterjest źle nazwany. Po czwarte, nie jest od razu oczywiste dla przyszłych programistów, że usuwa znaki na końcu łańcucha. Och, czekaj, to niekoniecznie tak robi. Przeszukuje ciąg. Może to być usunięcie gdzieś pośrodku. Teraz programista konserwacji musi zbadać wszystkie zastosowania metody, aby zobaczyć, co próbowano osiągnąć. Nie jest to dobra metoda wywoływania, ponieważ ta prosta potrzeba usunięcia z końca łańcucha. Przepraszam za całą krytykę; Robię to dla każdego, kto przyjmuje tę metodę, więc rozumieją.
ToolmakerSteve
Po piąte, w kontekście pytania String.TrimEndbyłoby bardziej odpowiednie zastosowanie. Ale czekaj, to już istnieje - i zostało wspomniane w pierwotnym pytaniu i kilku innych odpowiedziach 3 lata temu - nie trzeba wymyślać nowej metody! Jakie są zalety twojego podejścia?
ToolmakerSteve
7

Usuwa wszystkie przecinki końcowe:

while (strgroupids.EndsWith(","))
    strgroupids = strgroupids.Substring(0, strgroupids.Length - 1);

Jest to jednak odwrotnie, napisałeś kod, który dodaje przecinek w pierwszej kolejności. Powinieneś użyć string.Join(",",g)zamiast tego, zakładając, że gjest string[]. Nadaj mu lepszą nazwę niż gteż!

Kieren Johnstone
źródło
4

Zamiast dodawania przecinka dla każdego elementu można po prostu użyć String.Join:

var strgroupids = String.Join(",",  groupIds);

Spowoduje to dodanie separatora („,” w tym przypadku) między każdym elementem w tablicy.

Gary.S
źródło
3
string strgroupids = string.Empty;

groupIds.ForEach(g =>
{
    strgroupids = strgroupids + g.ToString() + ",";
});

strgroupids = strgroupids.Substring(0, strgroupids.Length - 1);

Zauważ, że użycie ForEachtutaj jest zwykle uważane za „złe” (czytaj na przykład http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx )

Korzystanie z LINQ:

string strgroupids = groupIds.Aggregate(string.Empty, (p, q) => p + q + ',');
strgroupids = strgroupids.Substring(0, str1.Length - 1);

Bez podciągów końcowych:

string strgroupids = groupIds.Aggregate(string.Empty, (p, q) => (p != string.Empty ? p + "," + q : q.ToString()));
Xanatos
źródło
1
@KierenJohnstone string.Joinjest idealny JEŻELI masz tablicę ciągów jako źródło LUB masz C # 4.0
xanatos
3

Dodatkowo do rozwiązania sll: Lepiej przyciąć łańcuch, jeśli na końcu są jakieś puste miejsca.

strgroupids = strgroupids.Remove(strgroupids.Trim().Length - 1);
tanzer
źródło
2

string.Joinjest lepszy, ale jeśli naprawdę chcesz LINQ ForEach:

var strgroupids = string.Empty;

groupIds.ForEach(g =>
{
    if(strgroupids != string.Empty){
        strgroupids += ",";
    }

    strgroupids += g;
});

Niektóre uwagi:

  • string.Joini foreachoba są lepsze niż to, znacznie wolniejsze podejście
  • Nie trzeba usuwać ostatniego, ,ponieważ nigdy nie jest dołączany
  • Operator increment ( +=) jest przydatny do dołączania do łańcuchów
  • .ToString() jest niepotrzebne, ponieważ jest wywoływane automatycznie podczas łączenia łańcuchów innych niż łańcuchy
  • Podczas obsługi dużych ciągów StringBuildernależy rozważyć zamiast łączenia ciągów

źródło
1
BŁĄD - trzeba cofnąć test if - powinien byćif(strgroupids != string.Empty){
ToolmakerSteve
Ale dziękuję za dodanie odpowiedzi, która pokazuje, jak użyć for-each do zbudowania łańcucha bez niechcianych „,” na końcu! Zauważ, że nie trzeba tworzyć lambda i ForEach; foreach (var g in groupIds) {działa równie dobrze :)
ToolmakerSteve
n1 @ToolmakerSteve, o LINQ, to jest kod OPs, który wziąłem