#angular #algorithm
Вопрос:
У меня есть 2-мерный массив бизнес-объектов, которые мне нужно преобразовать в их «модельное» представление (для последующей отправки на сервер).
Самое простое преобразование, которое приходит мне на ум, — это следующее:
private tiles: Array<Array<Tile>>;
...
let tileModels = this.tiles.map(_tiles=>_tiles.map(tile=>tile.generateModel()));
Это хорошо работает, если мой массив не пуст. Но в случае, если есть какой-либо нулевой объект, я получил ошибку:
Не удается прочитать свойство ‘generateModel’ значения null
Я могу преобразовать это преобразование во что-то вроде этого:
let tileModels = [];
this.tiles.forEach((_tiles) => {
let row = [];
_tiles.forEach((tile) => {
if (tile != undefined) {
row.push(tile.generateModel());
}
});
tileModels.push(row);
});
Но мне интересно, есть ли какой-нибудь лучший подход?
Спасибо!
P.S. Это в Angular 10/TS 4.1, но мне было бы интересно посмотреть трюки, которые можно выполнить на других языках.
Ответ №1:
Используйте дополнительный оператор цепочки:
tile?.generateModel()
Чтобы исключить эти неопределенные значения из результата, цепочка a filter
:
this.tiles.map(_tiles=>
_tiles.map(tile=>tile?.generateModel())
.filter(Boolean)
)
Если нет никаких шансов, что generateModel
это вернется undefined
, то вы можете сначала применить filter
то, а затем то map
.
И если вы хотите получить одномерный результат, то замените первый map
на flatMap
.
Комментарии:
1. Разве это не будет включено
undefined
в результирующий массив?2. См.Дополнение к ответу.
3. Спасибо! На самом деле, я пытался использовать «flatMap», но там говорится, что «Свойство»flatMap» не существует для типа » Плитка [] []»». Я думаю, это произойдет, если я введу отдельный класс (TilesArray) для плитки[] и буду использовать TilesArray[] в качестве типа для поля «плитки»? Но я не уверен, что это вообще возможно…?
4.
flatMap
поддерживается в узле 11 . Возможно, вам потребуется добавитьes2019
илиes2019.array
изменить--lib
настройки для распознавания машинописиflatMap()
.
Ответ №2:
Примените фильтр к массиву, чтобы убедиться, что вы удалили все null
значения.
const tileModels = this.tiles
.map(tileGroup=>tileGroup
.filter(tile=>!!tile)
.map(tile=>tile.generateModel())
);