Как сортировать и связывать в соответствии с ключами в Javascript - PullRequest
0 голосов
/ 16 февраля 2019

Прежде всего, я новичок в базе данных Nosql, но для моего приложения впервые попробовал использовать firebase.Я создаю приложение о чем-то, и в этом приложении у меня есть кандидаты, которые отправляют определенную сумму денег каждый месяц на определенную дату, чтобы сохранить, что в моем Firestore FireBase я создал транзакцию имени коллекции, и в этом для пользователя я сохраняю всеего транзакции.

transaction2018(collection) -> userId1(collection) -> { ....result1 }
                        -> userId2(collection) -> { ....result2 }
                     -> userId3(collection) -> { ....result3 }

transaction2019(collection) -> userId1(collection) -> { ....result1 }
                         -> userId2(collection) -> { ....result2 }
                         -> userId3(collection) -> { ....result3 }

Именно по этой причине я так и разработал, поэтому для каждого пользователя я могу получить все свои транзакции в одном объекте. Еще одна вещь в моем результирующем объекте amount_2, data_2 two - это фактическимесяц (февраль), и если я не сделаю этого, мне придется углубиться в что-то вроде:

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 голосов
/ 16 февраля 2019

Вы можете создать функцию, используя _.flow(), которая разбивает объект на массив записей (_.pairs()), группирует по номеру в ключе и затем отображает результат обратно в объект (_.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);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

И то же решение, используя lodash / fp :

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);
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
0 голосов
/ 16 февраля 2019

Вы можете сделать это простым JavaScript, используя Object.entries и Array.reduce, чтобы создать промежуточный словарь, ключи которого являются цифрами в конце ваших ключей.Это сгруппирует ваши пары ключ / значение по этой цифре, затем вы можете получить свой результат, взяв значения этого словаря, используя 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);
0 голосов
/ 16 февраля 2019

Вы можете рассмотреть возможность использования одного регулярного выражения для извлечения имени и номера из каждой клавиши объекта ввода (results) с помощью следующего:

const [, name, number] =  key.match(/^(.*)_(\d+)$/);

Где key - этотекущий ключ result повторяется.Это единственное регулярное выражение вернет name и number key в соответствии с форматом, который вы прописали.Полное решение может быть достигнуто независимо от lodash, как показано:

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"
};

/* Compose Object.values() and Object.entries() with reduce. Here we get
the key/value pairs (entries) of the input "results" object, and reduce
the key/values into an object of nsted objects of key/values grouped by 
number.
We then aquire an array of the grouped objects using Object.values() */
const groupedResult = Object.values(Object.entries(result).reduce((output, [key,value]) => {
   
  /* Extract key and number parts of current entry of result object */
  const [, name, number] =  key.match(/^(.*)_(\d+)$/);
  
  /* Fetch or insert (empty) object for the number corresponding to
  this entries key */
  const group = output[ number ] = output[ number ] || {}
  
  /* Compose a key with number suffix and insert value into group
  object for composed key */
  group[ `${name}${ number }` ] = value;
  
  /* Return current output object for next iteration of reduce */
  return output;

}, {}))

console.log(groupedResult);
0 голосов
/ 16 февраля 2019

Теперь кажется, что вы хотите сгруппировать поля в объекты в зависимости от чисел в хвосте каждого индекса.

const result = [];
_.each(inputObject, (key, value) => {
    const [,keyName, indexPart] = key.match(/^(.*)_(\d+)$/);
    result[indexPart] = result[indexPart] || {};
    result[indexPart][keyName] = value;
});
...