Załóżmy, że mam tablicę. Chcę usunąć wszystkie elementy w tablicy, które mają określoną wartość. Czy ktoś wie, jak to zrobić? Wartość, którą próbuję usunąć, może wystąpić więcej niż raz, a tablica nie musi być posortowana. Wolałbym filtrować tablicę w miejscu zamiast tworzyć nową tablicę. Na przykład usunięcie wartości 2
z tablicy [1, 2, 3, 2, 4]
powinno dać wynik [1, 3, 4]
.Usuwanie wszystkich wystąpień danej wartości z tablicy w D
To najlepsze, co mogłem wymyślić:
T[] without(T)(T[] stuff, T thingToExclude) {
auto length = stuff.length;
T[] result;
foreach (thing; stuff) {
if (thing != thingToExclude) {
result ~= thing;
}
}
return result;
}
stuff = stuff.without(thingToExclude);
writeln(stuff);
Wydaje się niepotrzebnie skomplikowane i nieefektywne. Czy jest prostszy sposób? Spojrzałem na moduł std.algorithm w standardowej bibliotece, mając nadzieję, że znajdę coś pożytecznego, ale wszystko, co wyglądałoby tak, by zrobiło to, co chciałem, było problematyczne. Oto kilka przykładów rzeczy próbowałem, które nie działały:
import std.stdio, std.algorithm, std.conv;
auto stuff = [1, 2, 3, 2, 4];
auto thingToExclude = 2;
/* Works fine with a hard-coded constant but compiler throws an error when
given a value unknowable by the compiler:
variable thingToExclude cannot be read at compile time */
stuff = filter!("a != " ~ to!string(thingToExclude))(stuff);
writeln(stuff);
/* Works fine if I pass the result directly to writeln but compiler throws
an error if I try assigning it to a variable such as stuff:
cannot implicitly convert expression (filter(stuff)) of type FilterResult!(__lambda2,int[]) to int[] */
stuff = filter!((a) { return a != thingToExclude; })(stuff);
writeln(stuff);
/* Mysterious error from compiler:
template to(A...) if (!isRawStaticArray!(A)) cannot be sliced with [] */
stuff = to!int[](filter!((a) { return a != thingToExclude; })(stuff));
writeln(stuff);
Więc Jak mogę usunąć wszystkie wystąpienia wartości z tablicy, nie wiedząc, gdzie indeksy są wyświetlane?
Problem z twoją ostatnią próbą to pierwszeństwo operatora: 'to! Int []' tworzy instancję szablonu 'to (T)', a następnie stosuje '[]', czyli operator plastra. Jeśli chcesz, aby nawiasy były częścią typu docelowego, potrzebujesz parens: 'to! (Int []) (...)'. To nadal nie zadziała, ale jest semantycznie poprawne. – scry