Как преобразовать объекты в матрице в другой тип?

#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())
  );