我正在读取带有制表符分隔值的文件,我想将其转换为带有命名属性的哈希数组。
我已经研究过the MDN page on Destructuring assignment,但是一些更复杂的例子对我没有意义,我没有看到导致单个对象的语法。
这是我到目前为止所得到的:
return File.readFile(filepath, 'utf8')
.then((fileContents) => fileContents.split('\n').map((line) => {
// here is where I'd convert the line of tab-separated
// text into an object with named properties
// this is fake, broken syntax
return ({ prop_a: [0], prop_b: [2], prop_c: [1] }) = line.split('\t');
}));
有几点需要注意:
File.readFile
是一个围绕节点原生fs.readFile(path, opt, callback)
API的简单ES6 Promise包装器。我正在寻找一个可以拆分line
并从中任意分配给新创建的对象的语句。我认为解构是解决这个问题的正确方法,但也许所需要的是例如休息或传播的一些创造性用途。
// sample input text
Ralphette dog 7
Felix cat 5
// desired output
[ { name: 'Ralphette', species: 'dog', age: '7' },
{ name: 'Felix' , species: 'cat', age: '5' }
]
感谢您的帮助!
ANSWER
听起来似乎没有办法只通过解构来做到这一点。然而,在混合物中引入IIFE使得单衬里具有不太奇特的解构。这是我使用的代码,基于@Amadan的答案:
return File.readFile(filepath, 'utf8')
.then((fileContents) => (fileContents.length === 0)
? []
: fileContents
.split('\n')
.map((line) => (([ name, species, age ]) => ({ name, species, age }))(line.split('\t')))
)
这很简洁,因此我建议不要在真实的项目中使用它。
如果,从现在开始,有人发现没有IIFE的方法,我希望他们会发布它。
答案 0 :(得分:3)
可能不是你想要的,但最接近的可能是
(x => ({ prop_a: x[0], prop_b: x[2], prop_c: x[1] }))(line.split('\t'));
但这可能是最容易做到的
var parts = line.split('\t');
return { prop_a: parts[0], prop_b: parts[2], prop_c: parts[1] };
虽然我可能被证明是错的,但我认为你想要的东西不能通过解构分配来完成。
答案 1 :(得分:3)
您无法将数组直接解构为对象
这个答案采用分解的方法,而不是将所有东西捆绑在一个大乱的功能中。这里的各个功能更易于编写,维护和测试。执行单个任务的小功能也更容易在程序的其他部分重用。
const lines = x => x.split("\n")
const cells = x => x.split("\t")
const makeObject = ([name, species, age]) => ({name, species, age})
const data = "Ralphette\tdog\t7\nFelix\tcat\t5"
const result = lines(data).map(x => makeObject(cells(x)))
console.log(result)
// [ { name: "Ralphette", species: "dog", age: "7" }
// , { name: "Felix", species: "cat", age: "5" }
// ]
如果您有compose
功能,它会变得更加清晰
const compose = (f,g) => x => f(g(x))
const result = lines(data).map(compose(makeObject,cells))
console.log(result)
// [ { name: "Ralphette", species: "dog", age: "7" }
// , { name: "Felix", species: "cat", age: "5" }
// ]
如果,从现在开始,有人发现没有IIFE的方法,我希望他们会发布它。
已经有几年了,所以这里是你的答案的编辑,不涉及立即调用的函数 -
File
.readFile(filepath, 'utf8')
.then
( fileContents =>
fileContents.length === 0
? []
: fileContents
.split('\n')
.map(line => line.split('\t'))
.map(([ name, species, age ]) => ({ name, species, age }))
)
这实际上与我上面的原始答案做了同样的事情,只是效率较低,因为它使用了两次map
调用。以下是将lines
,cells
和makeObject
与原始代码相关联的方法 -
File
.readfile(filepath, 'utf8')
.then
( fileContents =>
fileContents.length === 0
? []
: lines(fileContents).map(line => makeObject(cells(line))
)
还有一件事......
File.readFile
是一个围绕节点本地fs.readFile
(路径,选择,回调)API的简单ES6 Promise包装器
节点现在附带Promise-based API for the fs module。您可以简单地 - 而不是定义自己的包装器 -
const { readFile } = require("fs").promises
readFile(filePath, 'utf8').then(results => ...)
答案 2 :(得分:1)
这可能是另一个最接近的:
var parts = line.split('\t');
var [name, species, age] = parts;
return {name, species, age};