我有一个 Firebase 数据库,用于存储按日期排序的寄存器。日期的每一部分都是一个键。例如,对于日期 2017-12-01,集合是这样的:
2017 {
12 {
01 {
...registers
},
02 {
...registers
}
}
}
我认为提出这种结构的人(不是我)试图避免集合占用巨大的维度,这很好,但是:
我必须进行查询以过滤某个日期范围内的所有结果。选择一个初始日期和一个完成日期,您必须将所有寄存器存储到其中。
我是这样写的:
for (let index_year in results) {
if (parseInt(index_year) >= from_year && parseInt(index_year) <= to_year) {
for (let index_month in results[index_year]) {
if(parseInt(index_month) >= from_month && parseInt(index_month) <= to_month) {
for (let index_day in results[index_year][index_month]) {
if(parseInt(index_day) >= from_day && parseInt(index_day) <= to_day) {
items = results[index_year][index_month][index_day];
for (let id in items) {
console.log(items[id])
}
}
}
}
}
}
}
当所选日期在同一年内时,此方法工作正常。但是,如果您选择一个日期范围,例如:2017-12-01 到 2018-01-31,脚本根本不会返回结果。
你能想出一个更好的脚本来进行这个查询吗?有人做过类似的事情吗?
最佳答案
您可以将所需范围作为具有适当访问器的数组,并将该数组与数据映射。然后删除结果集的空洞。
在此示例中,范围从 2017-11-29
到 2017-12-06
,但并非所有日期都在可用对象中。
如果没有日期或内部属性的路径可用,则返回 undefined
。这需要在映射后进行过滤。
getData
使用层次结构并检查给定的属性。如果它得到 falsy value 它需要一个(几乎)空的对象来访问,它可能返回 undefined
、一个对象或一个值。
var data = { 2017: { 11: { 28: { data: '2017-11-28' }, 30: { data: '2017-11-30' } }, 12: { '01': { data: '2017-12-01' }, '03': { data: '2017-12-03' }, '05': { data: '2017-12-01' } } } },
range = [['2017', '11', '29'], ['2017', '11', '30'], ['2017', '12', '01'], ['2017', '12', '02'], ['2017', '12', '03'], ['2017', '12', '04'], ['2017', '12', '05'], ['2017', '12', '06']],
getData = (object, path) => path.reduce((o, k) => (o || {})[k], object),
result = range.map(date => getData(data, date)).filter(Boolean);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
关于javascript - 过滤按日期构造的javascript对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48080206/