int[] x = new int [] { 1, 2, 3};
int[] y = new int [] { 4, 5 };
int[] z = // your answer here...
Debug.Assert(z.SequenceEqual(new int[] { 1, 2, 3, 4, 5 }));
Teraz używam
int[] z = x.Concat(y).ToArray();
Czy istnieje łatwiejsza lub bardziej wydajna metoda?
Odpowiedzi:
źródło
params
.System.IO.Directory.GetFiles()
zwraca tablicę ciągów.Spróbuj tego:
źródło
List<int> list = new List<int>(x);
Możesz napisać metodę rozszerzenia:
Następnie:
źródło
Copy
szybsze niżCopyTo
? Możesz rozwinąć temat?Zdecydowałem się na bardziej ogólne rozwiązanie, które pozwala łączyć dowolny zestaw jednowymiarowych tablic tego samego typu. (Łączyłem 3+ na raz.)
Moja funkcja:
I użycie:
źródło
params T[][]
na,this T[][]
aby było to rozszerzenie.To jest to:
źródło
int[] result = array1.ToList().Concat(array2.ToList()).toArray();
że nie możesz nakładać Concat bezpośrednio na tablicetoArray()
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<string>' to 'string[]'. An explicit conversion exists (are you missing a cast?)
int[] result = ?
, jesteś ukrywanie problemu odpowiedź za swoimvar
IN że wynik będzieIEnumerable<int>
nieint[]
. (jeden z powodów, dla których nie lubięvar
zwrotów metod).ToArray()
wywołania ten kod nie zwróci faktycznej tablicy, więc jest to również niepoprawna odpowiedź.Możesz usunąć wywołanie ToArray () z końca. Czy istnieje powód, dla którego musisz być tablicą po wywołaniu Concat?
Wywołanie Concat tworzy iterator dla obu tablic. Nie tworzy nowej tablicy, więc nie użyłeś więcej pamięci dla nowej tablicy. Kiedy wywołujesz ToArray, faktycznie tworzysz nową tablicę i zajmujesz pamięć dla nowej tablicy.
Więc jeśli potrzebujesz po prostu iterować obie, po prostu zadzwoń do Concat.
źródło
Wiem, że OP był tylko lekko ciekawy wydajności. Większe tablice mogą uzyskać inny wynik (patrz @kurdishTree). I że zwykle nie ma to znaczenia (@ jordan.peoples). Niemniej jednak byłem ciekawy i dlatego straciłem zmysły (jak wyjaśniał @TigerShark) .... Mam na myśli, że napisałem prosty test oparty na pierwotnym pytaniu ... i wszystkich odpowiedziach ...
Wynik był:
Rzuć własne wygrane.
źródło
CopyTo
będzie pierwsza i ~ 3 razy szybsza niżRoll your own
.Uważaj na tę
Concat
metodę. Łączenie po tablicy macierzy w C # wyjaśnia, że:Będzie nieefektywny w przypadku dużych tablic. Oznacza to, że
Concat
metoda dotyczy tylko tablic wielkości meduim (do 10000 elementów).źródło
źródło
Bardziej wydajne (szybsze) do wykorzystania
Buffer.BlockCopy
w ciąguArray.CopyTo
,Napisałem prosty program testowy, który „rozgrzewa Jittera”, skompilowany w trybie wydania i uruchomił go bez dołączonego debugera na moim komputerze.
Dla 10 000 000 powtórzeń przykładu z pytania
Jeśli zmienię tablice testowe na dwie sekwencje od 0 do 99, otrzymam wyniki podobne do tego,
Na podstawie tych wyników mogę stwierdzić, że metody
CopyTo
iBlockCopy
są znacznie bardziej wydajne niż,Concat
a ponadto, jeśli wydajność jest celem,BlockCopy
ma przewagę nadCopyTo
.Aby odpowiedzieć na to pytanie, jeśli wydajność nie ma znaczenia lub będzie kilka iteracji, wybierz metodę, która jest dla ciebie najłatwiejsza.
Buffer.BlockCopy
oferuje pewne narzędzie do konwersji typów poza zakres tego pytania.źródło
Spóźniona odpowiedź :-).
źródło
Najbardziej wydajną strukturą pod względem pamięci RAM (i procesora) do przechowywania połączonej tablicy byłaby specjalna klasa, która implementuje IEnumerable (lub jeśli chcesz nawet wywodzi się z Array) i łączy wewnętrznie z oryginalnymi tablicami w celu odczytania wartości. AFAIK Concat właśnie to robi.
W przykładowym kodzie można pominąć .ToArray (), co zwiększyłoby jego wydajność.
źródło
Przykro mi, aby ożywić stary wątek, ale co z tym:
Następnie w kodzie:
Dopóki nie zadzwonisz
.ToArray()
,.ToList()
lub.ToDictionary(...)
pamięć nie zostanie przydzielona, możesz „zbudować zapytanie” i albo zadzwonić do jednego z tych trzech, aby je wykonać, lub po prostu przejrzeć je wszystkie, używającforeach (var i in z){...}
klauzuli, która zwraca element na raz zyield return t;
powyżej...Powyższą funkcję można przekształcić w rozszerzenie w następujący sposób:
Więc w kodzie możesz zrobić coś takiego:
Reszta jest taka sama jak poprzednio.
Kolejnym ulepszeniem tego byłoby przekształcenie się
T[]
wIEnumerable<T>
(takparams T[][]
by się stałoparams IEnumerable<T>[]
), aby te funkcje akceptowały więcej niż tylko tablice.Mam nadzieję że to pomoże.
źródło
Możesz to zrobić tak, jak to określiłeś, lub jeśli chcesz uzyskać naprawdę ręczną instrukcję, możesz stworzyć własną pętlę:
źródło
Znalazłem eleganckie jedno liniowe rozwiązanie wykorzystujące wyrażenie LINQ lub Lambda , oba działają tak samo (LINQ jest konwertowany na Lambda podczas kompilacji programu). Rozwiązanie działa dla dowolnego typu tablicy i dla dowolnej liczby tablic.
Za pomocą LINQ:
Korzystanie z Lambda:
Oba zapewniłem dla swoich preferencji. Pod względem wydajności rozwiązania @Sergey Shteyn lub @ deepee1 są nieco szybsze, a wyrażenie Lambda jest najwolniejsze. Czas potrzebny zależy od typu elementów tablicy, ale jeśli nie ma milionów wywołań, nie ma znaczącej różnicy między metodami.
źródło
Należy pamiętać, że podczas korzystania z LINQ korzystasz z opóźnionego wykonania. Wszystkie inne opisane tutaj metody działają doskonale, ale są wykonywane natychmiast. Ponadto funkcja Concat () jest prawdopodobnie zoptymalizowana w taki sposób, że nie można tego zrobić samodzielnie (wywołania wewnętrznych interfejsów API, wywołania systemu operacyjnego itp.). W każdym razie, chyba że naprawdę musisz spróbować zoptymalizować, jesteś obecnie na dobrej drodze do „źródła wszelkiego zła”;)
źródło
Spróbuj wykonać następujące czynności:
źródło
Oto moja odpowiedź:
Tej metody można użyć na poziomie inicjalizacji, na przykład w celu zdefiniowania statycznego konkatenacji tablic statycznych:
Zawiera jednak dwa zastrzeżenia, które należy wziąć pod uwagę:
Concat
Metoda tworzy iterator nad obu tablicach: nie tworzy nową tablicę, będąc w ten sposób efektywny pod względem pamięci używane: jednak późniejszeToArray
będą negować taką zaletę, ponieważ będzie on rzeczywiście stworzyć nową tablicę i zajmują pamięć dla nowa tablica.Concat
byłoby raczej nieefektywne w przypadku dużych tablic: powinno się go stosować tylko w przypadku tablic średnich.Jeśli dążenie do wydajności jest koniecznością, zamiast tego można zastosować następującą metodę:
Lub (dla fanów One-Liner):
Chociaż ta druga metoda jest znacznie bardziej elegancka, ta druga jest zdecydowanie lepsza pod względem wydajności.
Aby uzyskać dodatkowe informacje, zapoznaj się z tym postem na moim blogu.
źródło
Dla int [] to, co zrobiłeś, wygląda dla mnie dobrze. Odpowiedź osoby postronnej również by się sprawdziła
List<int>
.źródło
Dla mniejszych tablic <10000 elementów:
źródło
Myślę, że powyższe rozwiązanie jest bardziej ogólne i lżejsze niż inne, które tu widziałem. Jest bardziej ogólny, ponieważ nie ogranicza konkatenacji tylko dla dwóch tablic i jest lżejszy, ponieważ nie używa LINQ ani Listy.
Zwróć uwagę, że rozwiązanie jest zwięzłe, a dodana ogólność nie powoduje znaczącego obciążenia środowiska wykonawczego.
źródło
int [] x = new int [] {1, 2, 3}; int [] y = new int [] {4, 5};
int [] z = x.Union (y) .ToArray ();
źródło
Union
nie jest to bardzo dobry sposób, aby to zrobić, ponieważ domyślnie wywołujeDistinct
i usuwa wszelkie duplikaty z połączonej kolekcji.Concat
jest znacznie lepszy, ale jest już w pierwotnym pytaniu.źródło