Деструктурирование возможных нулевых значений в массиве

#javascript #arrays #null #object-destructuring #nullish-coalescing

Вопрос:

Есть ли лучший способ обработки null значений в приведенном ниже примере. В записях 5, 7 и 10 присутствует null значение.

Следующие ошибки отображаются независимо от того, является ли значение null или undefined .

 #5  - Uncaught TypeError: Cannot read property 'id' of null
#7  - Uncaught TypeError: object null is not iterable (cannot read property Symbol(Symbol.iterator))
#10 - Uncaught TypeError: Cannot read property 'id' of null
 
 const data = [
  { id: 1, children: [{ id: 'A' }] }, /*  1 */
  { id: 2, children: [{ id: 'B' }] }, /*  2 */
  { id: 3, children: [{ id: 'C' }] }, /*  3 */
  { id: 4, children: [{ }] },         /*  4 */
  //{ id: 5, children: [null] },      /*  5 */
  { id: 6, children: [] },            /*  6 */
  //{ id: 7, children: null },        /*  7 */
  { id: 8 },                          /*  8 */
  { },                                /*  9 */
  //null                              /* 10 */
];

const ids = data.map(
  ({
    id = -1,
    children: [
      {
        id: childId = -1
      } = {}
    ] = []
  } = {}) =>
    ({ id, childId })
);

console.log(ids); 
 .as-console-wrapper { top: 0; max-height: 100% !important; } 

Следующее работает, но менее элегантно. Это требует использования операторов, объединяющих нулевое значение (или логических операторов ИЛИ), необязательной цепочки и нескольких назначений.

 const data = [
  { id: 1, children: [{ id: 'A' }] }, /*  1 */
  { id: 2, children: [{ id: 'B' }] }, /*  2 */
  { id: 3, children: [{ id: 'C' }] }, /*  3 */
  { id: 4, children: [{}] },          /*  4 */
  { id: 5, children: [null] },        /*  5 */
  { id: 6, children: [] },            /*  6 */
  { id: 7, children: null },          /*  7 */
  { id: 8 },                          /*  8 */
  { },                                /*  9 */
  null                                /* 10 */
];

const ids = data.map(item => {
  const
    ref = item ?? {},
    children = ref.children ?? [],
    child = children[0] ?? {};
  return {
    id: ref?.id ?? -1,
    childId: child?.id ?? -1
  };
});

console.log(ids); 
 .as-console-wrapper { top: 0; max-height: 100% !important; } 

Я мог бы переписать это как вложенную ЖИЗНЬ, но следовать ей сложнее… Как вы можете видеть, я избегал использовать значения параметров по умолчанию, потому что вы можете только деструктировать undefined значения. Значение null является допустимым, поэтому я должен использовать логическое » ИЛИ » (операция слияния нулей тоже сработала бы), чтобы определить альтернативу.

 const data = [
  { id: 1, children: [{ id: 'A' }] },  /*  1       */
  { id: 2, children: [{ id: 'B' }] },  /*  2       */
  { id: 3, children: [{ id: 'C' }] },  /*  3       */
  { id: 4, children: [{ id: null }] }, /*  4 (NEW) */
  { id: 5, children: [{}] },           /*  5       */
  { id: 6, children: [null] },         /*  6       */
  { id: 7, children: [] },             /*  7       */
  { id: 8, children: null },           /*  8       */
  { id: 9 },                           /*  9       */
  { },                                 /* 10       */
  null                                 /* 11       */
];

const ids = data.map(item =>
  (ref =>
    ((id, children) =>
      (child =>
        ((childId) =>
          ({ id, childId }))
        (child.id || -1))
      (children[0] || {}))
    (ref.id || -1, ref.children || []))
  (item || {}));

console.log(ids); 
 .as-console-wrapper { top: 0; max-height: 100% !important; } 

Ответ №1:

Вы могли бы отказаться от множества заданий. Я не вижу никаких проблем с использованием нулевого объединения и необязательной цепочки.

 const data = [
  { id: 1, children: [{ id: 'A' }] },  /*  1       */
  { id: 2, children: [{ id: 'B' }] },  /*  2       */
  { id: 3, children: [{ id: 'C' }] },  /*  3       */
  { id: 4, children: [{ id: null }] }, /*  4 (NEW) */
  { id: 5, children: [{}] },           /*  5       */
  { id: 6, children: [null] },         /*  6       */
  { id: 7, children: [] },             /*  7       */
  { id: 8, children: null },           /*  8       */
  { id: 9 },                           /*  9       */
  { },                                 /* 10       */
  null                                 /* 11       */
];

const ids = data.map(item => ({
    id: item?.id ?? -1,
    childId: item?.children?.[0]?.id ?? -1
}));

console.log(ids); 
 .as-console-wrapper { top: 0; max-height: 100% !important; } 

Комментарии:

1. Может быть, это я, но я думаю, что на самом деле это намного более читабельно, чем любой из вариантов в вопросе