В С# какой самый короткий код для выравнивания массива?
Например, я хочу
[[1,2],[2,3],[4,5]]
в массив
[1,2,3,4,5]
Я ищу самый короткий способ сделать это.
В С# какой самый короткий код для выравнивания массива?
Например, я хочу
[[1,2],[2,3],[4,5]]
в массив
[1,2,3,4,5]
Я ищу самый короткий способ сделать это.
Возможно, я неправильно понимаю «кратчайший код», но я бы предложил использовать LINQ SelectMany
и Distinct
:
var values = new[]
{
new[] { 1, 2 },
new[] { 2, 3 },
new[] { 4, 5 },
};
var flattenedUniqueValues = values.SelectMany(x => x).Distinct();
Преобразование массива в шахматном порядке в одномерный массив просто и может быть выполнено в O(n)
времени и n
пространстве (где n
- это сумма длин массива 2-го измерения), однако в вашем примере вы, кажется, удаляете повторяющиеся значения - это не сглаживание массива, но это все еще можно сделать за O(n)
времени, но потребует O(2n)
места, потому что вам нужна хеш-таблица для O(1)
поиска повторяющихся значений.
Возможная проблема заключается в том, чтобы заранее знать, сколько элементов будет в конечном массиве. Простое решение — добавить к List<T>
и вызвать .ToArray()
в конце, но это приведет к O(2n)
времени и O(3n)
пространству (но потенциально больше из-за List<T>
внутренних перераспределений):
Int32[][] jagged = ...
HashSet<Int32> seen = new HashSet<Int32>();
List<Int32> ret = new List<Int32>();
for(int i = 0; i < jagged.Length; i++) {
for(int j = 0; j < jagged[i].Length; j++) {
Int32 val = jagged[i][j];
if( !seen.Contains( val ) ) {
ret.Add( val );
seen.Add( val );
}
}
}
return ret.ToArray(); // This takes O(n) time and will allocate O(n) additional space.
Существует еще одно решение, выполняющее 2 прохода самостоятельно: первый для определения размера вывода, затем второй проход для его генерации, что приведет к меньшему копированию: ровно O(2n)
времени и ровно O(2n)
места:
Int32[][] jagged = ...
HashSet<Int32> seen = new HashSet<Int32>();
// Pass 1
for(int i = 0; i < jagged.Length; i++) {
for(int j = 0; j < jagged[i].Length; j++) {
Int32 val = jagged[i][j];
seen.Add( val ); // HashSet.Add is safe/idempotent
}
}
Int32[] ret = new Int32[ seen.Count ];
// Pass 2
seen.Clear();
Int32 retIdx = 0;
for(int i = 0; i < jagged.Length; i++) {
for(int j = 0; j < jagged[i].Length; j++) {
Int32 val = jagged[i][j];
if( !seen.Contains( val ) ) {
ret[++retIdx] = val;
seen.Add( val );
}
}
}
return ret;