Стандартный метод для этого:
Преобразование структуры, ориентированной на строки (ячейки), в структуру, ориентированную на столбцы
Применить правильный глагол к каждому столбцу (только один раз)
Шаг (1) прост. Шаг (2) также прост, но не так очевиден. Есть небольшая хитрость, которая помогает.
Хитрость заключается в том, что ряд примитивных операторов принимают герунду в качестве левого аргумента и создают функцию, которая циклически обходит герунду, применяя каждый глагол по очереди. ИМО, самый полезный оператор в этой категории - ;.
. Вот пример реализации, использующей его:
Шаг (0), входы:
matrix =: ('abc';'defgh';23),:('foo';'bar';45)
columnTypes =: 'string';'string';'num'
DoString =: toupper
DoNum =: 0&j.
matrix
+---+-----+--+
|abc|defgh|23|
+---+-----+--+
|foo|bar |45|
+---+-----+--+
Шаг (1), сбор данных:
columnify =: <@:>"1@:|: :. rowify =: <"_1&>
columnify matrix
+---+-----+-----+
|abc|defgh|23 45|
|foo|bar | |
+---+-----+-----+
Обратите внимание, что столбец columnify снабжен обратным знаком, который приведет к повторной «сортировке» данных, хотя вы не должны этого делать: см. Ниже.
Шаг (2), примените правильный глагол к каждому столбцу (ровно один раз), используя функцию циклического глагола ;.
:
homogenize =: ({. foo&.>@:{.`'') [^:('foo'-:])L:0~ ]
chain =: DoString`DoNum`] homogenize@{~ ('string';'num')&i.
Обратите внимание, что преобразованием по умолчанию для неизвестных типов столбцов является функция тождества, ]
.
Глагол homogenize
нормализует ввод и вывод каждого процессора столбца (т. Е. Абстрагирует предварительную и последующую обработку, так что пользователю нужно только обеспечить динамическое «ядро» преобразования). Глагол chain
принимает список типов столбцов в качестве входных данных и получает герунду, подходящую для использования левого аргумента для ;.
(или аналогичного оператора).
Таким образом:
1 (chain columnTypes);.1 columnify matrix
+---+-----+---------+
|ABC|DEFGH|0j23 0j45|
|FOO|BAR | |
+---+-----+---------+
Или, если вам действительно нужна таблица ячеек в штучной упаковке NxM, примените вырезку «под» columnify:
1 (chain columnTypes);.1&.columnify matrix
+-----+-----+
|ABC |FOO |
+-----+-----+
|DEFGH|BAR |
+-----+-----+
|0j23 |0j45 |
+-----+-----+
Но обратите внимание гораздо более уместно в контексте J сохранять таблицу в виде списка однородных столбцов как для производительности, так и для обозначения.
J лучше всего работает при обработке массивов "in toto"; Практическое правило гласит, что примитивное или пользовательское имя должно видеть как можно больше данных в каждом приложении. В этом главное преимущество этого подхода "columificaton": если вы сохраняете ваши данные в виде списка однородных столбцов, это будет быстрее и проще манипулировать позже.
Однако, если ваш сценарий использования действительно требует, чтобы вы хранили данные в виде таблицы NxM в виде ячеек в штучной упаковке, то преобразование данных в обычную форму и из столбца является дорогостоящей операцией. В этом случае вам следует придерживаться вашего исходного решения,
1 chain\"1 matrix
, который (потому что вы спросили) на самом деле работает в той же предпосылке, что и ;.
подход. В частности, \
- это еще один из тех примитивных операторов, который принимает аргумент gerund и последовательно применяет каждый глагол (то есть к каждому новому окну данных, циклически).
Фактически 1 chain\"1 matrix
разбивает матрицу на строки ("1
) и для каждой строки создает движущееся окно шириной 1 (1 f\ matrix
), применяя глаголы chain
к каждому из этих окон шириной 1 (т.е. f
изменяется с каждым окном данных шириной 1 в каждой строке матрицы).
Поскольку движущееся окно 1 строки (вектор ранга 1) - это атомы строки по порядку, а глаголы chain
даны в том же порядке, в действительности вы применяете те глаголы к столбцам матрицы, один. атом. в. а. время.
Вкратце: 1 chain\"1 matrix
аналогично foo"0 matrix
, за исключением изменений foo для каждого атома. И этого следует избегать по той же причине: foo"0 matrix
следует вообще избегать: потому что применение функций с малым рангом работает против зерна J, влечет за собой снижение производительности.
В общем случае лучше использовать функции применения на более высоких рангах, когда это возможно, что в этом случае требует преобразования (и поддержания) matrix
в обычную для столбца форму.
Другими словами, здесь ;.
равно "1
, как \
равно "0
. Если вы обнаружите, что вся вещь columnify
/ homogenize
слишком длинная или громоздкая (по сравнению с 1 chain\"1 matrix
), вы можете импортировать скрипт, предоставленный в [1], который упаковывает эти определения как утилиты многократного использования с расширениями. Смотрите страницу с примерами и инструкциями.
[1] Связанный служебный скрипт:
http://www.jsoftware.com/jwiki/DanBron/Snippets/DOOG