Albo może po prostu keep it simple, wykorzystujących alternatywne PowerShell do operatora potrójnego:
foreach ($str in "hello", "good morning", "hi") {
$(if ($str.length -gt 4) { $str.substring(0, 4) } else { $str })
}
Podczas gdy wszystkie pozostałe odpowiedzi są "poprawne", ich efektywność zmienia się z nieoptymalnej na potencjalnie przerażającą. Poniższe nie stanowi krytyki innych odpowiedzi, ale ma na celu pouczające porównanie ich podstawowej działalności. W końcu tworzenie skryptów polega raczej na szybkim uruchomieniu systemu niż na szybkim uruchomieniu.
w celu:
1.
foreach ($str in "hello", "good morning", "hi") {
$str.subString(0, [System.Math]::Min(4, $str.Length))
}
To jest w zasadzie taka sama jak moja ofiara tą różnicą, że zamiast po prostu powrocie $ str, gdy jest zbyt krótki, wzywamy podciąg i poinformować go, aby powrócić cały ciąg. Stąd nieoptymalne. Nadal robi się, jeśli ... następnie ... ale tylko wewnątrz Min, vis.
if (4 -lt $str.length) {4} else {$str.length}
2.
foreach ($str in "hello", "good morning", "hi") { $str -replace '(.{4}).+','$1' }
Korzystanie wyrażenie regularne pasujące do chwycić pierwsze 4 znaki i wtedy wymienić cały łańcuch z nich oznacza, że cała (prawdopodobnie bardzo długo) łańcuch musi być skanowane przez dopasowanie silnik o nieznanej złożoności/wydajności. Podczas gdy osoba może zobaczyć, że ". +" Jest po prostu dopasowane do całej pozostałej części łańcucha, dopasowany silnik może budować dużą listę alternatyw cofania, ponieważ wzór nie jest zakotwiczony (nie^na początku). Tutaj (nieopisany) sprytny bit jest taki, że jeśli ciąg znaków jest mniejszy niż 5 znaków (4 razy, po którym następuje 1 lub więcej), to cały mecz kończy się niepowodzeniem i zastępuje zwrot $ str niezmieniony.
3.
foreach ($str in "hello", "good morning", "hi") {
try {
$str.subString(0, 4)
}
catch [ArgumentOutOfRangeException] {
$str
}
}
Celowo rzucanie wyjątki zamiast programowej kontroli granicznej jest ciekawym rozwiązaniem, ale kto wie, co się dzieje, gdy wyjątek propaguje się z bloku spróbować połowu. Prawdopodobnie niewiele w tym prostym przypadku, ale nie byłoby to zalecaną praktyką powszechną, z wyjątkiem sytuacji, w których istnieje wiele możliwych źródeł błędów (sprawiających kłopoty z sprawdzeniem ich wszystkich), ale tylko kilka odpowiedzi.
Co ciekawe, odpowiedź na podobne pytanie w innym miejscu za pomocą -join i plastry array (które nie powodują błędów na indeks poza zakresem, po prostu zignorować brakujących elementów)
$str[0..3] -join "" # infix
(lub prościej)
-join $str[0..3] # prefix
może być najbardziej efektywny (z odpowiednią optymalizacją), biorąc pod uwagę silne podobieństwo między przechowywaniem ciągów i znakami []. Optymalizacja byłaby wymagana, ponieważ domyślnie $ str [0..3] jest obiektem [], przy czym każdy element jest pojedynczym znakiem, a więc mało przypomina on ciąg (w pamięci). Nadanie PowerShell trochę wskazówka może być przydatna,
-join [char[]]$str[0..3]
Jednak może po prostu mówi to, co rzeczywiście chcą,
new-object string (,$str[0..3]) # need $str[0..3] to be a member of an array of constructor arguments
co bezpośrednio powołując
new String(char[])
jest najlepszy.
Chcesz dodać znaki, jeśli są krótsze i usunąć je, jeśli są dłuższe? – arco444
jeśli jest krótszy, zachowaj ciąg w obecnej postaci, bez potrzeby dodawania znaków. –