Функция Лодаша для разбиения коллекции на ключевые подколлекции - PullRequest
0 голосов
/ 13 января 2019

Ниже приведен пример черного ящика с чем-то вроде того, что я хотел бы сделать.

keyMany (arr: any[], cbk: (any) => string[])
  given that arr === [e1, e2, e3] (but could be any length);
  given cbk(e1) -> ['foo'];
  given cbk(e2) -> ['foo', 'bar'];
  given cbk(e3) -> ['baz', 'bar'];

тогда

output: {
  foo: [e1, e2],
  bar: [e2, e3],
  baz: [e3]
}

Чтобы подвести итог происходящему, первый аргумент, который является коллекцией, применяет cbk поэтапно, чтобы определить, к каким ключам в выводе должен быть элемент. Элемент может быть частью нескольких наборов ключей вывода.

Обратите внимание, что:

  1. Поскольку cbk, примененное к e1, приводит только к foo, e1 участвует только в наборе ключей вывода foo.
  2. Поскольку cbk, примененное к e2, приводит к foo & bar, e2 находится в наборах ключей вывода foo & bar.
  3. Аналогично для e3, только для наборов ключей bar & baz вместо.

В идеале e в выходной коллекции, если объекты, будут ссылочно эквивалентны e в входной коллекции.

Обратите внимание: первый вход

Мой вопрос: существует ли что-то подобное в Lodash? Избранные ответы на этот вопрос - да с номером версии или нет.

Кроме того, если такое поведение нелегко реализовать или это кажется полезным, у меня сейчас есть пиар на Lodash, чтобы добавить keyMany API: https://github.com/lodash/lodash/pull/4149/commits/cfe2918c905481f6f713be0a4e10cd4b60d32c4a

1 Ответ

0 голосов
/ 13 января 2019

Если я правильно понимаю ваш вопрос, то вы хотите создать словарь с ключами из значений подмассива, полученных в результате пользовательской функции обратного вызова.

В случае ваших данных / ввода одним из вариантов является использование Array#reduce() для достижения этой цели, как описано ниже:

// Mock setup data to support code snippet
var e1 = '0', e2 = '1', e3 = '2';
// Mock setup function to support code snippet
var cbk = (arg) => {
  switch(arg) {
    case e1: return ['a'];
    case e2: return ['a','b'];
    case e3: return ['b','c'];
  }
}

// Your input
var inputs = [e1,e2,e3];

// Process to aquire desired output
var output = inputs.reduce((result, inputValue) => {
  
  // Iterate callback result of each input value
  cbk(inputValue).forEach(cbkItem => {
    
    // Aquire array new or existing array that corresponds 
    // to this callback result's value (ie 'a', 'c', etc)
    var callbackResultArray = (result[ cbkItem ] || []);
    
    // Add current input value to callback result array
    callbackResultArray.push(inputValue);
    
    // Update result map with callback result array
    result[ cbkItem ] = callbackResultArray;
  
  });
  
  return result;

}, {});

console.log(output);
...