首先,我是Nosql数据库的新手,但对于我的应用程序,第一次尝试使用Firebase。 我正在创建有关某事的应用程序,在该应用程序中,我有一些申请人,他们每个月在特定日期提交一定金额的款项 为了将其存储在Firebase Firestore中,我创建了一个收藏名称交易,并为此保存了用户的所有交易。
transaction2018(collection) -> userId1(collection) -> { ....result1 }
-> userId2(collection) -> { ....result2 }
-> userId3(collection) -> { ....result3 }
transaction2019(collection) -> userId1(collection) -> { ....result1 }
-> userId2(collection) -> { ....result2 }
-> userId3(collection) -> { ....result3 }
这就是我如此设计的原因,因此我可以为每个用户 将他所有的交易都集中在一个对象中 对象数量_2,数据_2两个实际上是month(feb),如果我不这样做 这样我就必须更深入一些:
transaction2018 -> userId1 -> January -> {amount,date.....}
-> February
.....
在Nosql数据库中这实际上不是一个好习惯。
我正在使用NoSql数据库,得到的结果格式如下, 提取数据后如何将其转换为所需的格式:
let result = {
amount_2 : "1000",
amount_3 : "1200",
date_2 : "15/2/2019",
date_3 : "15/3/2019",
modeOfPayment_2: "Cash",
modeOfPayment_3: "Cash",
note_2 : "áßðáßðáßð↵áß",
note_3 : "",
refNum_2 : "11111",
refNum_3 : "Fffff",
submittedByID_2: "T62tgJcjieSJsAEJT69VfpRc5Mw2",
submittedByID_3: "T62tgJcjieSJ"
};
我想要类似的东西
var output = [
{
amount2,
date2,
....
},
{
amount3,
date3,
......
}
]
答案 0 :(得分:1)
您可以使用Object.entries
和Array.reduce
在普通的JavaScript中执行此操作,以构建一个中间字典,该字典的键是键末尾的数字。这样会将您的键/值对按该数字分组,然后您可以使用Object.values
获取该词典的值来获取结果。
使用key.match(/(\d+)$/)
,您可以提取按键末尾的数字,并将其用作中间词典的按键。
使用正向超前正则表达式/_(?=\d)/
,如果下划线位于键末尾的数字之前,则可以删除下划线以获取新的键名。
const data = {
amount_2 : "1000",
amount_3 : "1200",
date_2 : "15/2/2019",
date_3 : "15/3/2019",
modeOfPayment_2: "Cash",
modeOfPayment_3: "Cash",
note_2 : "áßðáßðáßð↵áß",
note_3 : "",
refNum_2 : "11111",
refNum_3 : "Fffff",
submittedByID_2: "T62tgJcjieSJsAEJT69VfpRc5Mw2",
submittedByID_3: "T62tgJcjieSJ"
};
const result = Object.values(Object.entries(data).reduce((dict, [key, val]) => {
// reduce is called for each key/value pair in your input data
// here we add the key/value pair in the proper entry based
// on the number extracted at the end
const num = key.match(/(\d+)$/); // get number at end of key
const newKey = key.replace(/_(?=\d)/, ''); // remove underscore before digit
dict[num] = dict[num] || {}; // create a default entry if needed
dict[num][newKey] = val; // set value for the new key
return dict; // return intermediate dictionary
}, {}));
console.log(result);
答案 1 :(得分:0)
现在,您似乎希望根据每个索引尾部的数字将字段分组为对象。
const result = [];
_.each(inputObject, (key, value) => {
const [,keyName, indexPart] = key.match(/^(.*)_(\d+)$/);
result[indexPart] = result[indexPart] || {};
result[indexPart][keyName] = value;
});
答案 2 :(得分:0)
您可能会考虑使用单个正则表达式通过以下操作从输入(results
)对象的每个键中提取名称和数字:
const [, name, number] = key.match(/^(.*)_(\d+)$/);
key
是要迭代的result
的当前键。该单个正则表达式将根据您指定的格式返回name
的{{1}}和number
。可以独立于lodash来实现完整的解决方案,如下所示:
key
答案 3 :(得分:0)
您可以使用_.flow()
创建一个函数,该函数将对象分解为条目数组(_.pairs()
),按键中的数字分组,然后将结果映射回对象({ {1}},并更新密钥(_.fromPairs
)。
_.mapKeys()
const { flow, toPairs, groupBy, partialRight: pr, map, fromPairs, mapKeys } = _;
const pattern = /_+(\d+)$/;
const getKeyId = ([k]) => (k.match(pattern) || [''])[0];
const fn = flow(
toPairs, // convert to entries
pr(groupBy, getKeyId), // group by the number in the key
pr(map, flow( // map back to object
fromPairs, // combine the entries in the group
pr(mapKeys, (v, k) => k.replace(pattern, '$1')) // update the keys
))
);
const data = {
amount_2 : "1000",
amount_3 : "1200",
date_2 : "15/2/2019",
date_3 : "15/3/2019",
modeOfPayment_2: "Cash",
modeOfPayment_3: "Cash",
note_2 : "áßðáßðáßð↵áß",
note_3 : "",
refNum_2 : "11111",
refNum_3 : "Fffff",
submittedByID_2: "T62tgJcjieSJsAEJT69VfpRc5Mw2",
submittedByID_3: "T62tgJcjieSJ"
};
const result = fn(data);
console.log(result);
和使用lodash/fp的相同解决方案:
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
const { flow, toPairs, groupBy, map, fromPairs, mapKeys, replace } = _;
const pattern = /_+(\d+)$/;
const getKeyId = ([k]) => (k.match(pattern) || [''])[0];
const fn = flow(
toPairs, // convert to entries
groupBy(getKeyId), // group by the number in the key
map(flow( // map back to object
fromPairs, // combine the entries in the group
mapKeys(replace(pattern, '$1')) // update the keys
))
);
const data = {
amount_2 : "1000",
amount_3 : "1200",
date_2 : "15/2/2019",
date_3 : "15/3/2019",
modeOfPayment_2: "Cash",
modeOfPayment_3: "Cash",
note_2 : "áßðáßðáßð↵áß",
note_3 : "",
refNum_2 : "11111",
refNum_3 : "Fffff",
submittedByID_2: "T62tgJcjieSJsAEJT69VfpRc5Mw2",
submittedByID_3: "T62tgJcjieSJ"
};
const result = fn(data);
console.log(result);