#javascript #arrays #multidimensional-array
#javascript #массивы #многомерный массив
Вопрос:
Могу ли я получить некоторые рекомендации о том, как извлечь несколько столбцов из двумерного массива, подобного приведенному ниже, используя JavaScript?
Array = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
];
простые методы, которые я видел до сих пор, используя forEach или map, позволят извлекать по ОДНОМУ столбцу за раз, есть ли способ вложить его каким-либо образом, чтобы извлечь индекс любого столбца, который вы пожелаете?
Допустим, столбец вывода desire равен 1,2 и 4.
Output = [
[1, 2, 4],
[5, 6, 8],
[9,10,12],
];
Редактировать:
Еще одна проблема, которую мне нужно решить, заключается в том, как удалить строку, если она Array [i] [1] = 0 или пуста.
Допустим, у нас есть дополнительные элементы массива…
Array = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
[13,0,15,16],
[17, ,19,20],
[21,22,23,24],
];
Желаемый результат получен сейчас…
Output = [
[1, 2, 4],
[5, 6, 8],
[9,10,12],
[21,22,24],
];
Комментарии:
1. я понятия не имею, чего вы хотите достичь, не могли бы вы добавить выходные данные вашего желания?
2. Можете ли вы показать пример желаемого результата, а также как вы будете указывать, какие столбцы вы хотите извлечь?
3. Это помогло бы показать, что вы пробовали, и желаемый результат, наряду с предлагаемым определением функции, если это все, что вы получили.
4. Вы можете использовать параметр index, подобный . array.map(элемент, индекс, массив)
Ответ №1:
Вы можете .map()
каждую строку из arr
преобразовать в новый массив, который вы можете получить, используя inner .map()
для массива столбцов / индексов, которые вы хотите получить. Внутренняя карта сопоставит каждый индекс с соответствующим значением из строки, предоставляя вам значения в каждом столбце для каждой строки.
Смотрите пример ниже:
const arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
];
const cols = [1, 2, 4];
const res = arr.map(r => cols.map(i => r[i-1]));
console.log(res);
Дополнительная информация: Как вы упомянули, первая карта предоставляет каждый внутренний массив внутри arr
функции внутреннего отображения:
cols.map(i => r[i-1])
Эта функция сопоставления будет перебирать индексы, определенные внутри cols
, и преобразовывать их в новое значение. Например, допустим, you’re r
— это второй массив:
[5, 6, 7, 8]
Выполнение cols.map(...)
приведет к циклическому перебору каждого элемента (обозначаемого i
в функции обратного вызова) в [1, 2, 4]
. Для каждого элемента мы «преобразуем» его в новый элемент:
i = 1
r = [5, 6, 7, 8]
new value: r[1-1] = 5
На следующей итерации мы рассмотрим следующее значение в cols
:
i = 2
r = [5, 6, 7, 8]
new value: r[2-1] = 6
Наконец, мы смотрим на конечное значение в cols
:
i = 4
r = [5, 6, 7, 8]
new value: r[4-1] = 8
Таким образом, функция сопоставления создает новый массив, который преобразует значения из cols [1, 2, 4]
в значения по тем индексам в текущей строке, которые должны быть [5, 6, 8]
. Это происходит для каждого внутреннего массива / строки, что приводит к конечному результату.
РЕДАКТИРОВАТЬ В соответствии с вашим редактированием, вы можете применить ту же логику, что и выше, чтобы получить ваши массивы только с теми столбцами, которые вы хотите. После того, как вы это сделаете, вы можете использовать .filter()
для сохранения только тех строк, которые имеют истинное значение во втором столбце. Сохранение всех массивов с истинными значениями во втором столбце приведет к удалению массивов с неистинными значениями во втором столбце (ложными значениями) из вашего результирующего массива. 0
и undefined
оба являются изменяемыми значениями, поэтому они не сохраняются.
Смотрите пример ниже:
const arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
[13,0,15,16],
[17, ,19,20],
[21,22,23,24],
]
const cols = [1, 2, 4];
const col = 2;
const res = arr.filter(r => r[col-1]).map(r => cols.map(i => r[i-1]));
console.log(res);
Если у вас есть несколько столбцов, которые вы хотите игнорировать, вы можете использовать .every()
, чтобы убедиться, что каждый столбец содержит истинное значение. Если они все это сделают, то .every()
вернутся true
с сохранением столбца, в противном случае он вернет false
, удалив столбец:
const arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
[13,0,15,16],
[ ,17,19,20],
[21,22,23,24],
]
const cols = [1, 2, 4];
const col = [1, 2];
const res = arr.filter(r => col.every(c => r[c-1])).map(r => cols.map(i => r[i-1]));
console.log(res);
Комментарии:
1. Работает великолепно!. Первая карта предоставляет доступ к каждому элементу в arr (r => cols.map(i => r[i-1])). Но точно, что происходит внутри этих скобок … немного за пределами моего понимания, можете ли вы помочь разработать, чтобы мы могли лучше понять, как это работает?
2. @user1488934 конечно, я пытался добавить еще несколько деталей. Короче говоря, внутренняя система
.map()
принимает значения изcols
и обрабатывает их как индексы. Таким образом, для текущего массиваr
он сопоставит каждое значение индексаi
изcols
со значением в этом индексе изr
3. @Nick_Parsons, если нам теперь требуется фильтровать col 1, а также 2; const col = [1,2]; , как мы могли бы это реализовать? Я пробовал const res = arr.map(r => cols.map(i => r[i-1])).filter(r => r [col.map(i => r [i-1]) -1]); Также для большого набора данных, скажем, с 30 столбцами и более 5000 строк; будет ли фильтр перед отображением более выгодным с точки зрения производительности?
4. Я обновил свой ответ (см. Последний скрытый фрагмент кода). Производительность для него будет N * M N * K, где N = размер
arr
, M = размерcols
, K = размерcol
. Если сначала выполнить фильтрацию, то производительность составит N * K X * M, где X = размер массива после фильтра. В худшем случае фильтр не удалит из вашего массива никаких элементовarr
, которые в этом случае X = N. Итак, вы правы. Выполнение фильтра перед отображением будет более производительным, так какX
обычно будет меньшеN
, что делает N * K X * M <= N * M N * K (таким образом, в принципе, использование filter перед отображением было бы более производительным)
Ответ №2:
Вы можете подойти к этому следующим образом. Решение заключается в использовании параметра index, доступного в методе filter .
Array.filter(currElem, индекс, массив)
Поскольку массив проиндексирован на 0, я создал массив с нужным вам индексом в данных как [0,1,3] . Вам нужно передать массив данных и массив индексов в функцию.
var array = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
];
var arrIndex = [0,1,3];
function extractData(arr,indexArr) {
return arr.map(obj => {
return obj.filter((ob,index) => {
if(indexArr.includes(index)){return ob}
})
})
}
console.log(extractData(array,arrIndex));