Ramda lib - javascript - рефакторинг / группировка данных - PullRequest
0 голосов
/ 24 января 2020

У меня есть некоторые необработанные данные о стране и времени начала, которые перечислены в данных, подобных этому

. Я пытаюсь использовать библиотеку ramda https://jsfiddle.net/0kdcvahw/

  var data = [
    {
      "label": "Argentina",
      "isIncluded": true,
      "times": [
        {"text": "", "starting_time": Date.parse('2020-01-14T10:00:00Z'), "ending_time": Date.parse('2020-02-14T15:20:00Z')}
      ]
    },
    {
      "label": "Chile",
      "isIncluded": true,
      "times": [
        {"text": "", "starting_time": Date.parse('2020-01-14T10:00:00'), "ending_time": Date.parse('2020-05-20T03:24:00')}
      ]
    },
    {
      "label": "United States of America",
      "isIncluded": true,
      "times": [
        {"text": "", "starting_time": Date.parse('2020-01-14T11:00:00Z'), "ending_time": Date.parse('2020-03-20T03:24:00')}
      ]
    }
  ];

и я хочу перенастроить список, чтобы он был более похож на этот

var data = [
    {
        label: 'Argentina, Chilie',
        value: 90,
    },
    {
        label: 'United States',
        value: 10,
    }
];

, так что в основном - есть 3 страны --- 2 из них стартуют в один и тот же день и в тот же час начала, например 10:00. - 1 начинается в тот же день, но 11: 00


пример кода - но необходимо удалить последнюю запятую

var data = [
    {
      "label": "Argentina",
      "isIncluded": true,
      "times": [
        {"text": "", "starting_time": Date.parse('2020-01-14T10:00:00Z'), "ending_time": Date.parse('2020-02-14T15:20:00Z')}
      ]
    },
    {
      "label": "Chile",
      "isIncluded": false,
      "times": [
        {"text": "", "starting_time": Date.parse('2020-01-14T10:00:00'), "ending_time": Date.parse('2020-05-20T03:24:00')}
      ]
    },
    {
      "label": "United States of America",
      "isIncluded": true,
      "times": [
        {"text": "", "starting_time": Date.parse('2020-01-14T11:00:00Z'), "ending_time": Date.parse('2020-03-20T03:24:00')}
      ]
    }
  ];


//console.log("data",data);
const groups = R.groupBy(x => x.times[0].starting_time, data);



const newData = Object.keys(groups).map(key => {
  return {
    label: groups[key].reduce((c, n) => `${c}${n.label}, `, ''),
    value: groups[key].length
  }
})

console.log('newData', newData)

Ответы [ 2 ]

1 голос
/ 24 января 2020

Вот подход Рамды:

const transform = pipe (
  groupBy (path (['times', 0, 'starting_time'])),
  values,
  map (applySpec ({
    label: pipe (pluck ('label'), join (', ')),
    value: length
  }))
)

const data = [{"isIncluded": true, "label": "Argentina", "times": [{"ending_time": 1581693600000, "starting_time": 1578996000000, "text": ""}]}, {"isIncluded": false, "label": "Chile", "times": [{"ending_time": 1589945040000, "starting_time": 1578996000000, "text": ""}]}, {"isIncluded": true, "label": "United States of America", "times": [{"ending_time": 1584674640000, "starting_time": 1578999600000, "text": ""}]}]

console .log (transform (data))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script>const {pipe, groupBy, path, values, map, applySpec, pluck, join, length} = R</script>

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

После этого это довольно простой код для Рамды. groupBy принимает функцию, которая дает вам канонический ключ для элемента. Здесь мы передаем результат path. path принимает массив строк или целых чисел и возвращает вам функцию, которая будет возвращать значение по этому пути входного объекта или неопределенную, если какой-либо из узлов не существует. groupBy (fn) возвращает объект с массивом для каждого из найденных канонических ключей, с элементами во входном массиве, разбитых на эти массивы.

Мы вызываем values для этого результата, который немного больше, чем ссылка на Object.values; он возвращает массив массивов.

В каждом из этих внешних массивов (через map) мы вызываем applySpec, который принимает отображение ключей на функции, создавая объект с теми ключами, значения которых результат применения соответствующей функции к вашему входному значению. Для value мы просто возвращаем length базового массива, а для label мы извлекаем label записей из каждого объекта, а затем соединяем их с ", ".

в ответах. здесь я часто показываю, как современный JS делает некоторые функции Ramda менее привлекательными. Хотя я мог бы сделать это здесь, комбинируя некоторые простые ES6 + -альтернативы с applySpec и values, используя простые лямбды для length и заменяя pipe (pluck ('label'), join (', ') чем-то вроде arr => arr .map (item => item .label) .join (', '). Но я не беспокоюсь, так как нам все равно придется написать одноразовый эквивалент groupBy. Хотя это не сложно, я думаю, что код будет значительно длиннее, чем этот. И я не вижу, чтобы это что-то получало. Конечно, я бы поступил так, если бы я еще не использовал Рамду в своем проекте, но в целом это хорошее время для использования упрощений Рамды.

1 голос
/ 24 января 2020

Подчеркивание имеет группу по функции здесь .

Возвращает граф объектов, заданный свойством, заданным в качестве группы, и значением являются объекты, которые соответствуют предоставленному ключу

const groups = groupBy(data, item => item.times[0].starting_time)

console.log('groups', groups)

const newData = Object.keys(groups).map(key => {
  return {
    label: groups[key].reduce((c, n) => `${c}${n.label}, `, '')
  }
})

console.log('newData', newData)
...