Aș dori să trunchez un șir de caractere astfel încât lungimea sa să nu fie mai mare decât o anumită valoare. Scriu într-un tabel de bază de date și vreau să mă asigur că valorile pe care le scriu respectă constrângerea de tip de date a coloanei.
De exemplu, ar fi bine dacă aș putea scrie următoarele:
string NormalizeLength(string value, int maxLength)
{
return value.Substring(0, maxLength);
}
Din păcate, acest lucru ridică o excepție deoarece maxLength
depășește în general limitele șirului de caractere value
. Desigur, aș putea să scriu o funcție de genul celei de mai jos, dar speram că există deja ceva asemănător.
string NormalizeLength(string value, int maxLength)
{
return value.Length <= maxLength ? value : value.Substring(0, maxLength);
}
Unde este API-ul evaziv care îndeplinește această sarcină? Există una?
Nu există un Truncate()
pe string, din păcate. Trebuie să scrieți singur acest tip de logică. Ceea ce poți face, totuși, este să înfășori acest lucru într-o metodă de extensie, astfel încât să nu trebuiască să o dublezi peste tot:
public static class StringExt
{
public static string Truncate(this string value, int maxLength)
{
if (string.IsNullOrEmpty(value)) return value;
return value.Length <= maxLength ? value : value.Substring(0, maxLength);
}
}
Acum putem scrie:
var someString = "...";
someString = someString.Truncate(2);
- Soluție grozavă, dar nu uitați că aceasta funcționează doar în NET 3.5 și mai sus. Nu o încercați în NET2.0. – > .
- Atâta timp cât sunteți în VS 2008 și, probabil, VS 2010, puteți face acest lucru chiar dacă vizați .Net 2.0. danielmoth.com/Blog/… – > .
- Acest lucru va eșua atunci când
maxLength
este o valoare negativă. – > . - @Bernard, acest lucru ar trebui să eșueze dacă maxLength este negativ. Orice alt comportament ar fi neașteptat. – > .
- Puteți apela metode de extensie pe valori nule. – > .
47
Sau, în loc de operatorul ternar, ați putea folosi Math.min
public static class StringExt
{
public static string Truncate( this string value, int maxLength )
{
if (string.IsNullOrEmpty(value)) { return value; }
return value.Substring(0, Math.Min(value.Length, maxLength));
}
}
- Inteligent! Iar următoarea expresie este optimizată pentru a returna o referință la șirul original:
value.Substring(0, value.Length)
. – > . - Din nefericire, nu este optimizată pentru cazurile în care value.Length este mai mică decât MaxLength, ceea ce poate fi un caz comun în unele date. De asemenea, proprietatea Length a șirului de caractere ar trebui să fie scrisă cu majuscule. – > .
- Acest lucru va eșua atunci când
maxLength
este o valoare negativă. – > . - @Bernard, la fel se va întâmpla și cu multe lucruri din cadru… dar dacă verific acest lucru… fie trebuie să fie implicit
maxLength
la0
fievalue.Length
; fie trebuie să arunc unArgumentOutOfRangeException
…ceea ce are mai mult sens în acest caz și este deja aruncat de cătreSubstring
în orice caz. – > . - Un pic mai scurt:
return string.IsNullOrEmpty(value) ? value : value.Substring(0, Math.Min(value.Length, maxLength));
– > .
M-am gândit să arunc în implementarea mea, deoarece cred că acoperă toate cazurile care au fost atinse de ceilalți și o face într-un mod concis, care este încă ușor de citit.
public static string Truncate(this string value, int maxLength)
{
if (!string.IsNullOrEmpty(value) && value.Length > maxLength)
{
return value.Substring(0, maxLength);
}
return value;
}
Această soluție se bazează în principal pe soluția lui Ray și deschide metoda pentru a fi utilizată ca metodă de extensie prin utilizarea this la fel cum face LBushkin în soluția sa.
- Aceasta va eșua atunci când
maxLength
este o valoare negativă. – > . - @Bernard – V-aș recomanda să nu treceți o valoare negativă pentru argumentul maxLength, deoarece este o valoare neașteptată. Metoda Substring are aceeași abordare, deci nu există niciun motiv pentru a îmbunătăți excepția pe care o aruncă. – > .
- Nu cred că verificarea IsNullOrEmpty este necesară? (1) Dacă valoarea este nulă, nu ar trebui să existe nicio modalitate de a apela această metodă de extensie asupra ei. (2) Dacă valoarea este un șir de caractere gol, verificarea value.Length > maxLength va eșua. – > .
- @JonSchneider, IsNullOrEmpty este necesară deoarece aceasta este o metodă de extensie. Dacă aveți o variabilă de tip string căreia i s-a atribuit un null, compilatorul nu inserează o verificare null înainte de a apela această metodă. Din punct de vedere tehnic, aceasta este încă o metodă statică a clasei static. Deci: stringVar.Truncate(2) Se compilează ca: StringExt.Truncate(stringVar, 2); – – > .
- Lipsa unui
IsNullOrEmpty
și a rezultatuluiNullReferenceException
este o caracteristică, nu o eroare. La fel ca șistr.Substring(0,10)
aruncă dacăstr
este nul, este logic castr.Truncate(10)
să facă același lucru. – > .
16
Pentru că testarea performanței este distractivă: (folosind metodele de extensie linqpad)
var val = string.Concat(Enumerable.Range(0, 50).Select(i => i % 10));
foreach(var limit in new[] { 10, 25, 44, 64 })
new Perf<string> {
{ "newstring" + limit, n => new string(val.Take(limit).ToArray()) },
{ "concat" + limit, n => string.Concat(val.Take(limit)) },
{ "truncate" + limit, n => val.Substring(0, Math.Min(val.Length, limit)) },
{ "smart-trunc" + limit, n => val.Length <= limit ? val : val.Substring(0, limit) },
{ "stringbuilder" + limit, n => new StringBuilder(val, 0, Math.Min(val.Length, limit), limit).ToString() },
}.Vs();
The truncate
metoda a fost „semnificativ” mai rapidă. #microoptimizare
La început
- truncate10 5788 ticuri scurse (0.5788 ms) [în 10K repetări, 5.788E-05 ms per].
- smart-trunc10 8206 ticuri scurse (0.8206 ms) [în 10K repetări, 8.206E-05 ms per].
- stringbuilder10 10557 ticks scurse (1.0557 ms) [în 10K repetări, 0.00010557 ms per]
- concat10 45495 ticks scurse (4.5495 ms) [în 10K repetări, 0.00045495 ms per]
- newstring10 72535 ticks scurse (7,2535 ms) [în 10K repetări, 0,00072535 ms per]
Late
- truncate44 8835 ticks scurse (0.8835 ms) [în 10K repetări, 8.835E-05 ms per]
- stringbuilder44 13106 ticks scurse (1.3106 ms) [în 10K repetări, 0.00013106 ms per]
- smart-trunc44 14821 ticks elapsed (1.4821 ms) [în 10K repetări, 0.00014821 ms per]
- newstring44 144324 ticks scurse (14.4324 ms) [în 10K repetări, 0.00144324 ms per]
- concat44 174610 ticks scurse (17.461 ms) [în 10K repetări, 0.0017461 ms per]
Prea mult timp
- smart-trunc64 6944 ticks elapsed (0.6944 ms) [în 10K reps, 6.944E-05 ms per]
- truncate64 7686 ticks elapsed (0.7686 ms) [în 10K reps, 7.686E-05 ms per]
- stringbuilder64 13314 ticks scurse (1.3314 ms) [în 10K repetări, 0.00013314 ms per]
- newstring64 177481 ticks scurse (17.7481 ms) [în 10K repetări, 0.00177481 ms per]
- concat64 241601 ticks scurse (24.1601 ms) [în 10K repetări, 0.00241601 ms per]
- Vă mulțumim pentru toate aceste repere utile! … și Linkpad este grozav! – > .
- Hmm, nu sunt de acord cu acest bench. 1) Șirul de intrare
val
este o constantă. 2) Lungimea de trunchierelimit
este constantă pentru toate cele 10k iterații. 3) Se pare că ieșirea este imediat eliminată. Toți acești factori pot determina compilatorul să optimizeze lucrurile. Mi-am făcut propriul test și am constatat că ceea ce numiți „smart-trunc” este în medie semnificativ (20%) mai rapid decât „truncate”, și asta cu 10M de iterații în modul de lansare/producție (am constatat, de asemenea, o diferență semnificativă între rularea în modul Debug și modul Release). > . - @JHBonarius m-am gândit că avertismentul YMMV pentru testele de performanță ar trebui să fie oarecum evident și am vrut doar să pun mingea la bătaie 😉 și chiar dacă ai perfectă dreptate, nu uita că vorbim despre diferențe mai mici de o miime de milisecundă… – > .
În .NET 4.0 puteți utiliza Take
metoda :
string.Concat(myString.Take(maxLength));
Nu a fost testată pentru eficiență!
Ați putea folosi LINQ… elimină necesitatea de a verifica lungimea șirului. Recunosc că poate nu este cel mai eficient, dar este distractiv.
string result = string.Join("", value.Take(maxLength)); // .NET 4 Join
sau
string result = new string(value.Take(maxLength).ToArray());
- de ce nu este acesta răspunsul acceptat? Ce este cel mai simplu, să vă scrieți propria metodă de extensie pe care trebuie să o mențineți/documentați sau să folosiți ceva încorporat, cum ar fi .Take – > .
- @mmcrae Linq ar putea fi mai direct, dar este, de asemenea, mult mai lent. Benchmark-ul meu spune ~400ms pentru Linq și doar ~24ms pentru Substring pentru 1 milion de iterații. – > .
- Această soluție nu ar trebui să fie folosită niciodată. După cum s-a spus în cele două comentarii de mai sus, există întotdeauna alocare de memorie, chiar și atunci când șirul existent nu este mai mare decât lungimea maximă. De asemenea, este foarte lentă. – > .
O altă soluție:
return input.Substring(0, Math.Min(input.Length, maxLength));
- Soluție foarte elegantă +1 – > .
Am făcut-o pe a mea într-o singură linie, cam așa
value = value.Length > 1000 ? value.Substring(0, 1000) : value;
- -1; acest lucru nu adaugă absolut nimic care să nu fi fost deja în răspunsul acceptat. – > .
- @markamery este o alternativă mai scurtă, cu mai puțin cod de scris și de actualizat atunci când trebuie să o folosești. Nu vă place? Nu o folosiți. > .
- Rapid, simplu și rapid. Asta este ceea ce aveam nevoie. Mulțumesc! – > .
.NET Framework are un API pentru a trunchia un șir de caractere ca acesta:
Microsoft.VisualBasic.Strings.Left(string, int);
Dar într-o aplicație C# veți prefera, probabil, să vă creați propria aplicație decât să vă faceți dependență de Microsoft.VisualBasic.dll, a cărui principală rațiune de a fi este compatibilitatea cu versiunile anterioare.
- „The .NET Framework are un API” vă contraziceți. Aceasta este o API VB.NET – > .
- @CamiloTerevinto – este un API care este livrat cu .NET Framework și poate fi apelat din orice limbaj administrat. – > .
- DLL-ul VB are o mulțime de lucruri bune în el. De ce sunt atât de mulți dezvoltatori c# împotriva ei? – > .
- Din păcate, în prezent nu există suport pentru .NET Core. Într-adevăr, întregul
Microsoft.VisualBasic.Strings
module în .NET Core este destul de goală. – > . - Deși sunt de acord cu comentariul lui Joe, totuși nu mă simt bine să numesc ceva specific pentru VB din alte limbaje. Dacă există atât de multe lucruri bune în „VB DLL”, de ce să nu le punem într-un loc comun? Cine știe ce va face Microsoft cu aceste lucruri mâine? O să oprească suportul sau ceva de genul… > .
Se pare că nimeni nu a postat asta încă:
public static class StringExt
{
public static string Truncate(this string s, int maxLength)
{
return s != null && s.Length > maxLength ? s.Substring(0, maxLength) : s;
}
}
Folosirea operatorului && îl face marginal mai bun decât răspunsul acceptat.
Știu că este o întrebare veche, dar iată o soluție frumoasă:
public static string Truncate(this string text, int maxLength, string suffix = "...")
{
string str = text;
if (maxLength > 0)
{
int length = maxLength - suffix.Length;
if (length <= 0)
{
return str;
}
if ((text != null) && (text.Length > maxLength))
{
return (text.Substring(0, length).TrimEnd(new char[0]) + suffix);
}
}
return str;
}
var myString = "hello world"
var myTruncatedString = myString.Truncate(4);
Returnează: hello…
- @SarjanWebDev Acest caracter special apare ca „.” în cmd.exe – > .
O variantă similară cu operatorul de propagare Null din C# 6
public static string Truncate(this string value, int maxLength)
{
return value?.Length <= maxLength ? value : value?.Substring(0, maxLength);
}
Vă rugăm să rețineți că, în esență, verificăm dacă value
este nul de două ori aici.
Încă nu există o metodă Truncate în 2016 pentru șirurile C#. Dar – Folosind sintaxa C# 6.0:
public static class StringExtension
{
public static string Truncate(this string s, int max)
{
return s?.Length > max ? s.Substring(0, max) : s ?? throw new ArgumentNullException(s);
}
}
Funcționează ca un farmec:
"Truncate me".Truncate(8);
Result: "Truncate"
De ce nu:
string NormalizeLength(string value, int maxLength)
{
//check String.IsNullOrEmpty(value) and act on it.
return value.PadRight(maxLength).Substring(0, maxLength);
}
adică în evenimentul value.Length < maxLength
se introduc spații la sfârșit sau se trunchiază excesul.
- Se generează de două ori mai multe obiecte de tip șir de caractere și s-ar putea să se arunce o excepție NullReferenceException din apelul PadRight dacă valoarea este nulă, ceea ce este inadecvat, ar trebui să fie o excepție ArgumentNullException. – > .
- @Jeremy Nu înțeleg ” ar putea să arunce o NullReferenceException din apelul PadRight dacă valoarea este nulă”; nu am menționat „//verifică string.IsNullOrEmpty(value) și acționează în consecință.”. – > .
În C# 8 se poate utiliza noua caracteristică Ranges…
value = value[..Math.Min(30, value.Length)];
Luând @CaffGeek și simplificându-l:
public static string Truncate(this string value, int maxLength)
{
return string.IsNullOrEmpty(value) ? value : value.Substring(0, Math.Min(value.Length, maxLength));
}
Kndly rețineți că trunchierea unui șir nu înseamnă pur și simplu justing tăierea unui șir doar la o lungime specificată, dar trebuie să aveți grijă să nu divizați cuvântul.
De exemplu, șirul: acesta este un șir de test.
Vreau să-l tai la 11 . Dacă folosim oricare dintre metodele prezentate mai sus, rezultatul va fi
acesta este un șir de caractere
Acesta nu este lucrul pe care îl dorim
Metoda pe care o folosesc eu poate că nu este perfectă, dar poate rezolva majoritatea situațiilor.
public string CutString(string source, int length)
{
if (source== null || source.Length < length)
{
return source;
}
int nextSpace = source.LastIndexOf(" ", length);
return string.Format("{0}...", input.Substring(0, (nextSpace > 0) ? nextSpace : length).Trim());
}
În cazul în care nu sunt suficiente răspunsuri aici, iată-l pe al meu 🙂
public static string Truncate(this string str,
int totalLength,
string truncationIndicator = "")
{
if (string.IsNullOrEmpty(str) || str.Length < totalLength)
return str;
return str.Substring(0, totalLength - truncationIndicator.Length)
+ truncationIndicator;
}
pentru a utiliza:
"I use it like this".Truncate(5,"~")
Cei doi cenți ai mei cu o lungime de exemplu de 30 :
var truncatedInput = string.IsNullOrEmpty(input) ?
string.Empty :
input.Substring(0, Math.Min(input.Length, 30));
Cea mai simplă metodă în C# recent ar fi:
string Trunc(string s, int len) => s?.Length > len ? s.Substring(0, len) : s;
Aceasta returnează valoarea trunchiată pentru șirurile mai lungi și șirul original pentru celelalte cazuri – inclusiv intrarea nulă – care este tratată de operatorul unar ?
De dragul (supra)complexității voi adăuga versiunea mea supraîncărcată care înlocuiește ultimele 3 caractere cu o elipsă în respect cu parametrul maxLength.
public static string Truncate(this string value, int maxLength, bool replaceTruncatedCharWithEllipsis = false)
{
if (replaceTruncatedCharWithEllipsis && maxLength <= 3)
throw new ArgumentOutOfRangeException("maxLength",
"maxLength should be greater than three when replacing with an ellipsis.");
if (String.IsNullOrWhiteSpace(value))
return String.Empty;
if (replaceTruncatedCharWithEllipsis &&
value.Length > maxLength)
{
return value.Substring(0, maxLength - 3) + "...";
}
return value.Substring(0, Math.Min(value.Length, maxLength));
}
Știu că există deja o tonă de răspunsuri aici, dar acesta este cel pe care l-am ales eu, care tratează atât șirurile de caractere nule, cât și situația în care lungimea transmisă este negativă:
public static string Truncate(this string s, int length)
{
return string.IsNullOrEmpty(s) || s.Length <= length ? s
: length <= 0 ? string.Empty
: s.Substring(0, length);
}
Prefer răspunsul lui jpierson, dar niciunul dintre exemplele de aici pe care le pot vedea nu gestionează un parametru maxLength invalid, cum ar fi atunci când maxLength < 0.
Opțiunile ar fi fie să tratăm eroarea într-un try/catch, să fixăm parametrul maxLength min la 0, fie, dacă maxLength este mai mic de 0, să returnăm un șir gol.
Nu este un cod optimizat:
public string Truncate(this string value, int maximumLength)
{
if (string.IsNullOrEmpty(value) == true) { return value; }
if (maximumLen < 0) { return String.Empty; }
if (value.Length > maximumLength) { return value.Substring(0, maximumLength); }
return value;
}
- Rețineți că, în implementarea mea, am ales să nu gestionez cazul în care lungimea maximă este mai mică de 0, deoarece m-am gândit că singurul lucru pe care l-aș putea face ar fi să arunc un ArgumentOutOfOfRangeExcpetion, ceea ce, în esență, face string.Substring() pentru mine. – > .
Iată o soluție vb.net, rețineți că instrucțiunea if (deși urâtă) îmbunătățește performanța deoarece nu avem nevoie de instrucțiunea substring atunci când șirul este deja mai mic decât maxlength…Făcând-o o extensie a șirului, este ușor de utilizat…
<System.Runtime.CompilerServices.Extension()> _
Public Function Truncate(String__1 As String, maxlength As Integer) As String
If Not String.IsNullOrEmpty(String__1) AndAlso String__1.Length > maxlength Then
Return String__1.Substring(0, maxlength)
Else
Return String__1
End If
End Function
- În VB.net puteți înlocui „Not String.IsNullOrEmpty(String__1)” cu „String__1 <> Nothing”. Este un pic mai scurt. Valoarea implicită pentru șiruri de caractere este un șir gol. Folosind „<> Nothing” se verifică atât cazul null, cât și cel al șirului gol. Testați-o cu: Truncate(„”, 50) și Truncate(Nothing, 50) – > .
- În VB puteți face Left(string, maxlength) – > .
Știu că există deja o tonă de răspunsuri, dar nevoia mea era să păstrez intact începutul și sfârșitul șirului, dar să-l scurtez sub lungimea maximă.
public static string TruncateMiddle(string source)
{
if (String.IsNullOrWhiteSpace(source) || source.Length < 260)
return source;
return string.Format("{0}...{1}",
source.Substring(0, 235),
source.Substring(source.Length - 20));
}
Acest lucru este pentru crearea de URL-uri SharePoint care au o lungime maximă de 260 de caractere.
Nu am făcut din lungime un parametru, deoarece este o constantă 260. De asemenea, nu am făcut din lungimea primului subșir un parametru, deoarece vreau ca acesta să se întrerupă într-un anumit punct. În cele din urmă, al doilea subșir este lungimea sursei – 20, deoarece cunosc structura dosarului.
Acest lucru ar putea fi ușor adaptat la nevoile dvs. specifice.
Biblioteca populară Humanizer are o Trunchiat metoda Pentru a o instala cu NuGet:
Install-Package Humanizer
Nu există nimic în .net pentru acest lucru, din câte știu eu – iată versiunea mea care adaugă „…”:
public static string truncateString(string originalString, int length) {
if (string.IsNullOrEmpty(originalString)) {
return originalString;
}
if (originalString.Length > length) {
return originalString.Substring(0, length) + "...";
}
else {
return originalString;
}
}
- Versiunea dvs. va oferi șiruri de caractere care sunt cu 3 caractere mai lungi decât lungimea solicitată, în cazul în care sunt trunchiate. În plus, punctele triple sunt de fapt doar semnificative în reprezentare, nu le-aș stoca într-o bază de date ca aceasta, care este cazul de utilizare pe care l-a dat OP. – > .
TruncateString
public static string _TruncateString(string input, int charaterlimit)
{
int characterLimit = charaterlimit;
string output = input;
// Check if the string is longer than the allowed amount
// otherwise do nothing
if (output.Length > characterLimit && characterLimit > 0)
{
// cut the string down to the maximum number of characters
output = output.Substring(0, characterLimit);
// Check if the character right after the truncate point was a space
// if not, we are in the middle of a word and need to remove the rest of it
if (input.Substring(output.Length, 1) != " ")
{
int LastSpace = output.LastIndexOf(" ");
// if we found a space then, cut back to that space
if (LastSpace != -1)
{
output = output.Substring(0, LastSpace);
}
}
// Finally, add the "..."
output += "...";
}
return output;
}
- De ce precedeți numele metodei publice cu o subliniere? – > .
Ca o completare la posibilitățile discutate mai sus, aș dori să vă împărtășesc soluția mea.Este o metodă de extensie care permite null (returnează string.Empty), de asemenea, există un al doilea .Truncate() pentru a o utiliza cu o elipsă. Atenție, nu este optimizată din punct de vedere al performanței.
public static string Truncate(this string value, int maxLength) =>
(value ?? string.Empty).Substring(0, (value?.Length ?? 0) <= (maxLength < 0 ? 0 : maxLength) ? (value?.Length ?? 0) : (maxLength < 0 ? 0 : maxLength));
public static string Truncate(this string value, int maxLength, string ellipsis) =>
string.Concat(value.Truncate(maxLength - (((value?.Length ?? 0) > maxLength ? ellipsis : null)?.Length ?? 0)), ((value?.Length ?? 0) > maxLength ? ellipsis : null)).Truncate(maxLength);
Puteți crea o metodă Truncate
metodă de extensie care compară lungimea maximă în raport cu lungimea șirului de caractere și apelează la Substring
dacă este necesar.
Dacă doriți un comportament de tratare a valorilor nule care să fie similar cu cel al metodei Substring
, nu includeți o verificare a caracterului nul. În acest fel, la fel ca str.Substring(0, 10)
aruncă un NullReferenceException
dacă str
este nul, la fel va face și str.Truncate(10)
.
public static class StringExtensions
{
public static string Truncate(this string value, int maxLength) =>
value.Length <= maxLength ? value : value.Substring(0, maxLength);
}
Pe baza acestui lucru și a acestui lucru, iată două versiuni care vor funcționa și pentru valorile negative ale valorilor „până la”. Aceasta dintâi nu permite valori negative în mod silențios prin plafonarea la 0:
public static string Truncate(this string value, int maxLength)
{
return string.IsNullOrEmpty(value) ?
value :
value.Substring(0, Math.Max(0, Math.Min(value.Length, maxLength)));
}
Aceasta merge în cerc:
private static int Mod(this int a, int n) => (((a %= n) < 0) ? n : 0) + a;
public static string Truncate(this string value, int maxLength)
{
return string.IsNullOrEmpty(value) ?
value :
value.Substring(0, maxLength.Mod(value.Length));
}
Iată o C# 9 de o linie:
public static string Truncate(this string value, int maxLength) => value is null or "" || value.Length <= maxLength ? value : value[..maxLength];
public static string Truncate( this string value, int maxLength )
{
if (string.IsNullOrEmpty(value)) { return value; }
return new string(value.Take(maxLength).ToArray());// use LINQ and be happy
}
- The
ToArray()
aici este doar un efort inutil; folosind, de ex.String.Concat
puteți construi un șir de caractere dintr-o enumerare de caractere fără a fi nevoie să treceți printr-un array. – > .
Trunchiați șirul de caractere
public static string TruncateText(string strText, int intLength)
{
if (!(string.IsNullOrEmpty(strText)))
{
// split the text.
var words = strText.Split(' ');
// calculate the number of words
// based on the provided characters length
// use an average of 7.6 chars per word.
int wordLength = Convert.ToInt32(Math.Ceiling(intLength / 7.6));
// if the text is shorter than the length,
// display the text without changing it.
if (words.Length <= wordLength)
return strText.Trim();
// put together a shorter text
// based on the number of words
return string.Join(" ", words.Take(wordLength)) + " ...".Trim();
}
else
{
return "";
}
}
- Acest lucru nu răspunde la întrebarea lui OP. În primul rând, ar trebui să fie o funcție membră (deși ați scris-o ca o metodă de extensie). În al doilea rând, OP nu specifică faptul că textul trebuie să fie divizat, iar cuvintele trebuie să fie trunchiate la aproximativ 7,6 caractere pe cuvânt. – > .
- 7,6 este doar un număr. puteți scrie orice alt număr doriți. S-a întâmplat ca aceasta să fie o lungime medie a cuvintelor în limba engleză. Am găsit-o pe Google. Utilizarea divizării este doar o modalitate ușoară de a împărți cuvintele în funcție de spațiu. Nu cred că doriți să afișați o jumătate de cuvânt! Deci, dacă nu faceți o buclă pentru a găsi spațiile goale, ceea ce va necesita mai mult cod, aceasta este o modalitate ușoară de a trunchia un șir și de a afișa cuvinte întregi. Acest lucru vă va asigura că un șir nu este mai lung decât lungimea dată și nu veți avea cuvinte întrerupte. – > .
Acesta este codul pe care îl folosesc de obicei:
string getSubString(string value, int index, int length)
{
if (string.IsNullOrEmpty(value) || value.Length <= length)
{
return value;
}
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for (int i = index; i < length; i++)
{
sb.AppendLine(value[i].ToString());
}
return sb.ToString();
}
- Rețineți că concatenarea șirurilor de caractere cu += este o operațiune costisitoare, mai ales atunci când se reconstruiește caracter cu caracter. Șirurile .NET sunt imuabile, ceea ce înseamnă că, în acest caz, un nou șir este creat de fiecare dată în bucla dvs. – > .
- @SteveGuidi șirurile de caractere nu sunt imuabile, ele doar se prefac că sunt imuabile. Mi-aș dori ca șirurile să fie adevărate primitive imuabile, astfel încât să pot avea șiruri și șiruri?, dar din păcate nu sunt primitive. – > .
- Spuneți scump ca și cum costul de performanță ar fi semnificativ, am schimbat-o pentru a folosi stringBuilder, dar mi se pare că cu += este mai ușor de văzut ce se întâmplă, am vrut doar ca OP să înțeleagă cu ușurință codul. – > .
Aș recomanda utilizarea metodei substring pentru aceeași funcționalitate eficientă.
// Gets first n characters.
string subString = inputString.Substring(0, n);
Aceasta are avantajul de a vă permite să îmbinați șirul din ambele părți sau chiar undeva la mijloc fără a scrie metode suplimentare. Sper că vă ajută 🙂
Pentru referință suplimentară: https://www.dotnetperls.com/substring
- Dacă șirul dvs. este mai mic decât n, va eșua. Scopul trunchierii este de a preveni acest lucru. – > .
25- Pentru înregistrare, șirurile de caractere sunt imuabile, nu le poți trunchia, poți doar să returnezi o copie trunchiată a lor. Știu că e o problemă de rigoare. – > Por John Weldon.
- @John Weldon: Probabil că acesta este motivul pentru care funcția membră nu există – nu respectă semantica tipului de date. Pe o notă secundară,
- Indiferent de soluția pe care o alegeți, asigurați-vă că adăugați o verificare pentru un șir nul înainte de a apela Substring sau de a accesa proprietatea Length. – > Por Ray.
- @SteveGuidi – Dacă ar fi așa, atunci nu ar exista funcții precum Trim sau Replace, care se confruntă cu probleme semantice similare – > Por Chris Rogers.
- @JohnWeldon Mai prudenți decât sunt în mod constant cei de la Microsoft, după cum se întâmplă – sunt fericiți să documenteze, de exemplu,
StringBuilder
vă permite să trunchiați prin scurtarea lungimii, dar tot trebuie să efectuați verificarea lungimii pentru a evita lărgirea șirului. – > Por Steve Guidi..Trim()
într-o manieră care face să pară în mod înșelător că modifică șirul de caractere: „Îndepărtează toate caracterele de început și sfârșit de spațiu alb din obiectul String curent.” – > Por Mark Amery.