Существует ли сокращенный способ преобразования элементов массива в свойства объекта?

#javascript #ecmascript-6

#javascript #ecmascript-6

Вопрос:

Я прочитал MDN и увидел все изящные трюки, которые можно выполнить с помощью операторов rest и spread и деструктурирования массива, и теперь мне интересно, есть ли способ быстро сопоставить элементы массива со свойствами именованных объектов.

У меня есть несколько значений, разделенных табуляцией в виде обычного текста (копирование из электронной таблицы), и прямо сейчас у меня есть что-то более или менее похожее на это:

 const tsv = `1  Jim Robinson    Company Co. Active
2   Fred Jimmyson   Examples Inc.   Inactive
3   Rob Freddison   Company Co. Active`;

const badgeTable = tsv.split('n').map(e => {
    let tmp = {};
    [ tmp.id, tmp.name, tmp.company, tmp.status ] = e.split('t')
    return tmp
})
  

В принципе, мне интересно, есть ли способ избавиться от tmp переменной, которую я использую в функции map, и напрямую разделить текст на объект с именами свойств.
Я попытался использовать оператор распространения, например:

 const badgeTable = tsv.split('n').map(e => ({0:id, 1:name, 2:company, 4:status} = {...e.split('t')}))
  

Но он не назвал свойства так, как я хотел, вместо этого просто используя индексы массива в качестве имен свойств.

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

1. Вероятно, есть способ сделать это, используя reduce и массив имен свойств.

2. @jfriend00 Разделен табуляцией.

Ответ №1:

Если вы создаете массив свойств заранее, вы можете использовать Object.fromEntries для сопоставления каждого разделенного элемента с записью в создаваемом объекте:

 const tsv = `1  Jim Robinson    Company Co.  Active
2   Fred Jimmyson   Examples Inc.   Inactive
3   Rob Freddison   Company Co.  Active`;


const properties = ['id', 'name', 'company', 'status'];
const badgeTable = tsv.split('n').map(
  e => Object.fromEntries(
    e.split(/s{2,}/)
      .map((value, i) => [properties[i], value])
  )
);

console.log(badgeTable);  

(Я разделил на /s{2,}/ в приведенном выше фрагменте просто для того, чтобы фрагмент выполнялся, поскольку Stack Exchange отображал ваши вкладки как пробелы и имеет проблемы с пробелами табуляции — ваш оригинал t будет отлично работать в вашем реальном коде)

Ответ №2:

Вы можете использовать reduce() для заполнения объекта при циклическом перемещении по элементам массива.

reduce() получает индекс массива в качестве третьего аргумента, его можно использовать для индексации в массив имен свойств.

 const tsv = `1  Jim Robinson    Company Co.  Active
2   Fred Jimmyson   Examples Inc.   Inactive
3   Rob Freddison   Company Co.  Active`;


const properties = ['id', 'name', 'company', 'status'];
const badgeTable = tsv.split('n').map(
  line => line.split(/s{2,}/)
  .reduce((obj, cur, i) => (obj[properties[i]] = cur, obj), {})
);

console.log(badgeTable);  

Я скопировал хак @CertainPerformance, чтобы разделить входные строки на несколько пробелов.