Como excluir o último caractere em uma string em c #?

94

Construindo uma string para post request da seguinte maneira,

  var itemsToAdd = sl.SelProds.ToList();
  if (sl.SelProds.Count() != 0)
  {
      foreach (var item in itemsToAdd)
      {
        paramstr = paramstr + string.Format("productID={0}&", item.prodID.ToString());
      }
  }

depois de obter o resultado paramstr, preciso excluir o último caractere &nele

Como excluir o último caractere em uma string usando c #?

rem
fonte
2
Acho que é melhor não adicioná-lo em primeiro lugar, mas caso contrário, você pode tentar paramstr.Substring (0, paramstr.Length - 1)
Jaco Pretorius
No caso de seu prodID conter caracteres arbitrários, especialmente &, você precisa se certificar de que ele tenha um escape adequado, como, por exemplo, a resposta de @MarcGravell.
Eugene Beresovsky

Respostas:

75

construa com string.Join:

var parameters = sl.SelProds.Select(x=>"productID="+x.prodID).ToArray();
paramstr = string.Join("&", parameters);

string.Joinpega um separador ( "&") ee array de strings ( parameters), e insere o separador entre cada elemento do array.

Rob Fonseca-Ensor
fonte
1
É importante notar que isso é útil se você não quiser ter um sinal & no final da string.
Ammar,
Eu sabia que isso estava em Ruby, não fazia ideia que estava em C # e sou um desenvolvedor .net. Eu me sinto tão envergonhado lol
Jack Marchetti
Não acredito que essa foi a resposta escolhida ... a que está logo abaixo dessa por @BrianRasmussen é muito mais simples.
FastTrack
@FastTrack Resolveu o problema raiz, em vez de responder à pergunta do título. Minha reclamação: se você quer ser fluente, por que não fazer tudo em uma linha.
Graham
241

Pessoalmente, eu aceitaria a sugestão de Rob, mas se você quiser remover um (ou mais) caractere (s) final (is) específico (s), você pode usar TrimEnd. Por exemplo

paramstr = paramstr.TrimEnd('&');
Brian Rasmussen
fonte
15
Esteja ciente de que TrimEnd removerá todas as ocorrências finais desse caractere '&' ... portanto, se a string terminar com '&&&', então TrimEnd removerá todos os três '&', não apenas o último. Isso pode ou não ser o que o OP deseja.
Doug S
3
@DougS FWIW Eu escrevi "remover um (ou mais)".
Brian Rasmussen,
+1 para uma solução simples, que pode assim ser facilmente utilizada como um componente para outros problemas. Eu estava procurando uma solução para criar um caminho de várias partes garantindo que eu não tivesse barras duplas ou barras ausentes. Combinar TrimEnd e TrimStart com esta técnica garante isso.
Joeppie
1
@Joeppie: sugira o uso Path.Combine, que entende todos os separadores de caminho. Pelo menos use o Trimque começa e termina de uma vez.
Nigel Touch de
@Nigel, o problema que tenho com Path.Combine é que se o segundo argumento começar com uma barra, ele será interpretado como um caminho absoluto e o resultado será o caminho absoluto; isso é algo que eu prefiro 'salvar' as pessoas que chamam meu código. Bom ponto sobre o trim :)
Joeppie
22
string source;
// source gets initialized
string dest;
if (source.Length > 0)
{
    dest = source.Substring(0, source.Length - 1);
}
Steve Townsend
fonte
15

Experimente isto:

paramstr.Remove((paramstr.Length-1),1);
Nelson T Joseph
fonte
2
Você explicaria um pouco sua resposta, para que outras pessoas que vierem tenham uma ideia melhor do motivo da sua sugestão?
Andrew Barber de
1
A resposta de @Altaf Patel usa o método irmão String.Remove Method (Int32), que é indiscutivelmente mais direto nessa situação. No entanto, é bom saber sobre String.Remove Method (Int32, Int32) que oferece a capacidade de cortar uma substring de comprimento arbitrário de qualquer lugar dentro da string de origem.
DavidRR de
13

Eu simplesmente não o adicionaria em primeiro lugar:

 var sb = new StringBuilder();

 bool first = true;
 foreach (var foo in items) {
    if (first)
        first = false;
    else
        sb.Append('&');

    // for example:
    var escapedValue = System.Web.HttpUtility.UrlEncode(foo);

    sb.Append(key).Append('=').Append(escapedValue);
 }

 var s = sb.ToString();
Marc Gravell
fonte
Não vou dizer nada sobre a legibilidade deste trecho, mas é assim que eu faria.
Matti Virkkunen
2
Também é barato e fácil encurtar o comprimento do StringBuilder em um após o término do loop.
Matt Greer
+1 para não adicioná-lo ao invés de removê-lo, para usar um StringBuilder em vez de + =, e para encadear anexos em vez de concatenar e anexar. :)
Guffa
1
O problema com essa solução é que o operador "if" é chamado de "n" vezes.
Magallanes
11
string str="This is test string.";
str=str.Remove(str.Length-1);
Altaf Patel
fonte
1
From String.Remove Method (Int32) : "Retorna uma nova string na qual todos os caracteres na instância atual, começando em uma posição especificada e continuando até a última posição, foram excluídos."
DavidRR de
7

É melhor se você usar string.Join.

 class Product
 {
   public int ProductID { get; set; }
 }
 static void Main(string[] args)
 {
   List<Product> products = new List<Product>()
      {   
         new Product { ProductID = 1 },
         new Product { ProductID = 2 },
         new Product { ProductID = 3 }
      };
   string theURL = string.Join("&", products.Select(p => string.Format("productID={0}", p.ProductID)));
   Console.WriteLine(theURL);
 }
Cheng Chen
fonte
Você está faltando .ToArray()em sua Joindeclaração. 1 embora. Me ajudou.
desaivv
1
@desaivv: Não, eu estava usando esta sobrecarga:, public static string Join<T>(string separator, IEnumerable<T> values)é novo em C # 4.0 :)
Cheng Chen
Ahh meu mal. Ainda usando VS2008 com 3.0
desaivv
5

É uma boa prática usar um StringBuilderao concatenar muitas strings e você pode usar o método Remove para se livrar do caractere final.

StringBuilder paramBuilder = new StringBuilder();

foreach (var item in itemsToAdd)
{
    paramBuilder.AppendFormat(("productID={0}&", item.prodID.ToString());
}

if (paramBuilder.Length > 1)
    paramBuilder.Remove(paramBuilder.Length-1, 1);

string s = paramBuilder.ToString();
Dan Diplo
fonte
Também lembrei que você também pode usar paramBuilder.Length - 1para remover o último caractere.
Dan Diplo de
1
paramstr.Remove((paramstr.Length-1),1);

Isso funciona para remover um único caractere do final de uma string. Mas se eu usá-lo para remover, digamos, 4 caracteres, isso não funcionará:

paramstr.Remove((paramstr.Length-4),1);

Como alternativa, usei esta abordagem:

DateFrom = DateFrom.Substring(0, DateFrom.Length-4);
Uzair Zaman Sheikh
fonte
2
Usando Método String.Remove (Int32, Int32) , para remover 4 caracteres a partir da extremidade de uma cadeia de caracteres: result = source.Remove((source.Length - 4), 4);.
DavidRR de
0

Adicione um StringBuilder extension method.

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

então use:

yourStringBuilder.RemoveLast(",");
Nznoor
fonte