#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, чтобы разделить входные строки на несколько пробелов.