问题描述
概述:我有一个对象数组 (arr)。我需要将看起来像 ISO 时间戳的对象中的任何值转换为纪元。我通过正则表达式匹配。
{
assignee: null
color: null
description: "cool object"
id: "12234858"
last_updated: "2021-01-22T15:30:10.495000+00:00"
}
arr.forEach((item) => {
let regex = /^[+-]?\d{4}(-[01]\d(-[0-3]\d(T[0-2]\d:[0-5]\d:?([0-5]\d(\.\d+)?)?[+-][0-2]\d:[0-5]\dZ?)?)?)?/;
Object.entries(myobject).forEach(([key,value]) => {
if (value !== null) {
if (value.match(regex)) {
value = Date.parse(value) / 1000;
}
}
});
});
日期转换在迭代每个对象的键和值时起作用,但是一旦 arr.forEach() 完成,这些值就会重置。处理这些转换的最佳方法是什么?我应该映射到新对象并复制吗?
解决方法
值本身是一个原语,它不保留与它所取自的对象的“连接”。您需要使用已解构的键将值分配回项目。
注意:您的正则表达式实际上不起作用,并将其他值检测为日期。解析并检查值是否为 NaN
会更容易。请参阅此answer。
const arr = [{
assignee: null,color: null,description: "cool object",id: "12234858",last_updated: "2021-01-22T15:30:10.495000+00:00",}];
arr.forEach((item) => {
Object.entries(item).forEach(([key,value]) => {
if (!isNaN(Date.parse(value || ''))) {
// assign the new value back to the original item
item[key] = Date.parse(value) / 1000;
}
});
});
console.log(arr);
如 @NicholasCarey's comment 所述,!isNaN(Date.parse())
可能会将其他字符串标识为日期。因此,如果您遇到误报,您可能需要使用正则表达式(取自此 answer)或更严格的库:
const arr = [{
assignee: null,}];
const regex = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/;
arr.forEach((item) => {
Object.entries(item).forEach(([key,value]) => {
if (regex.test(value || '')) {
// assign the new value back to the original item
item[key] = Date.parse(value) / 1000;
}
});
});
console.log(arr);
我会使用像 Luxon 这样的库。像这样:
const {DateTime} = require('luxon');
function transformIso8601ToSomethingUsable(arr) {
for ( const obj of arr ) {
for ( const [k,v] of Object.entries(obj) ) {
obj[k] = iso8601DateTime2epochTime(v);
}
}
}
function iso8601DateTime2epochTime(s) {
const dt = DateTime.fromISO(s).toUTC();
const epochTime = dt.isValid
? Math.round(dt.toSeconds())
: s ;
return epochTime;
}
然后你可以这样说
const arr = [{
assignee: null,}];
transformIso8601ToSomethingUsable(arr);
并得到
[
{
"assignee": null,"color": null,"description": "cool object","id": "12234858","last_updated": 1611329410
}
]