如何按照Javascript中的键进行排序和配对

时间:2019-02-16 08:38:05

标签: javascript lodash

首先,我是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,
   ...... 
  }
]

4 个答案:

答案 0 :(得分:1)

您可以使用Object.entriesArray.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);