使用文件名作为键将文件数组转换为对象的更简洁的方法
More concise way to convert an array of files into object, using the filename as key
我正在使用 Node.js 从文件夹加载文件数组并创建对象数组:
var files = {}
fs.readdirSync(dir).forEach(function(file) {
files[file] = fs.readFileSync(dir + '/' + file)
})
这似乎我应该能够在不先定义对象的情况下做到这一点,也许使用 .map()
?
理论上你可以做到
Object.assign({}, ...fs.readdirSync(dir) .
map(
file => ({[file]: fs.readFileSync(dir + '/' + file})
)
);
是否更多 "concise" 由您决定。
reduce 解决方案是
fs.readdirSync(dir) .
reduce(
(result, file) => {
result[file] = fs.readFileSync(dir + '/' + file);
return result;
},
{}
);
或
fs.readdirSync(dir) .
reduce(
(result, file) =>
result.defineProperty(file, {
value: fs.readFileSync(dir + '/' + file)
}),
{}
);
None 这些似乎与您提出的代码一样明显。
Underscore 可以将成对数组转换为对象,因此您可以这样做
_.object(fs.readdirSync(dir) .
map(
file =>
[file, fs.readFileSync(dir + '/' + file]
)
);
正如其他人提到的,你可以用这个(可以说更丑)reduce
。
var files = fs.readdirSync(dir).reduce(function(files, file) {
files[file] = fs.readFileSync(dir + '/' + file);
return files;
}, {});
为了更好用,您可以将它包装在一个辅助函数中,甚至可以扩展 Array 原型(不建议,但它 看起来 更干净)。
function log(msg) {
document.querySelector('pre').innerText += msg + '\n';
}
var filesInDir = ['a.txt', 'b.txt', 'c.txt'];
var files;
// Helper function
function toObject(arr, map) {
return arr.reduce(function(obj, value) {
obj[value] = map(value);
return obj;
}, {});
};
files = toObject(filesInDir, function(file) {
return file + '_mapped';
});
log('Helper');
log(JSON.stringify(files, null, 2));
// Modify the prototype (not recommended)
Array.prototype.toObject = function(map) {
return this.reduce(function(obj, value) {
obj[value] = map(value);
return obj;
}, {});
};
files = filesInDir.toObject(function(file) {
return file + '_mapped';
});
log('Prototype');
log(JSON.stringify(files, null, 2));
<pre></pre>
使用地图无法重现您的示例。它将构造一个对象数组。整个练习本质上是一个微优化,你所做的工作和可读性强,所以我建议只使用它。
就是说,如果您真的愿意,您可以移动对象定义,我将在此处展示一个小示例,只是为了展示选项
var files = fs.readdirSync(dir).reduce(function(obj,file) {
return (obj[file] = fs.readFileSync(dir + '/' + file),obj)
},{})
我正在使用 Node.js 从文件夹加载文件数组并创建对象数组:
var files = {}
fs.readdirSync(dir).forEach(function(file) {
files[file] = fs.readFileSync(dir + '/' + file)
})
这似乎我应该能够在不先定义对象的情况下做到这一点,也许使用 .map()
?
理论上你可以做到
Object.assign({}, ...fs.readdirSync(dir) .
map(
file => ({[file]: fs.readFileSync(dir + '/' + file})
)
);
是否更多 "concise" 由您决定。
reduce 解决方案是
fs.readdirSync(dir) .
reduce(
(result, file) => {
result[file] = fs.readFileSync(dir + '/' + file);
return result;
},
{}
);
或
fs.readdirSync(dir) .
reduce(
(result, file) =>
result.defineProperty(file, {
value: fs.readFileSync(dir + '/' + file)
}),
{}
);
None 这些似乎与您提出的代码一样明显。
Underscore 可以将成对数组转换为对象,因此您可以这样做
_.object(fs.readdirSync(dir) .
map(
file =>
[file, fs.readFileSync(dir + '/' + file]
)
);
正如其他人提到的,你可以用这个(可以说更丑)reduce
。
var files = fs.readdirSync(dir).reduce(function(files, file) {
files[file] = fs.readFileSync(dir + '/' + file);
return files;
}, {});
为了更好用,您可以将它包装在一个辅助函数中,甚至可以扩展 Array 原型(不建议,但它 看起来 更干净)。
function log(msg) {
document.querySelector('pre').innerText += msg + '\n';
}
var filesInDir = ['a.txt', 'b.txt', 'c.txt'];
var files;
// Helper function
function toObject(arr, map) {
return arr.reduce(function(obj, value) {
obj[value] = map(value);
return obj;
}, {});
};
files = toObject(filesInDir, function(file) {
return file + '_mapped';
});
log('Helper');
log(JSON.stringify(files, null, 2));
// Modify the prototype (not recommended)
Array.prototype.toObject = function(map) {
return this.reduce(function(obj, value) {
obj[value] = map(value);
return obj;
}, {});
};
files = filesInDir.toObject(function(file) {
return file + '_mapped';
});
log('Prototype');
log(JSON.stringify(files, null, 2));
<pre></pre>
使用地图无法重现您的示例。它将构造一个对象数组。整个练习本质上是一个微优化,你所做的工作和可读性强,所以我建议只使用它。
就是说,如果您真的愿意,您可以移动对象定义,我将在此处展示一个小示例,只是为了展示选项
var files = fs.readdirSync(dir).reduce(function(obj,file) {
return (obj[file] = fs.readFileSync(dir + '/' + file),obj)
},{})