Как использовать Lodash's unionBy и объединять вложенные массивы? - PullRequest
0 голосов
/ 20 ноября 2018

Я ищу, чтобы объединить / объединить объекты в массиве каждый с последовательностью вложенных массивов.Я хочу объединить объекты на основе определенного ключа (здесь label[1]).Я могу использовать Lodash и unionBy для фильтрации дубликатов по label[1], но как мне сохранить значения отфильтрованных элементов?

Массив может выглядеть так:

var arr = [{
    "label": ['item', 'private'],
    "values": [1, 2, 3]
  },
  {
    "label": ['item', 'private'],
    "values": [1, 2, 3, 6]
  },
  {
    "label": ['item', 'work'],
    "values": [1, 2, 8, 9]
  },
  {
    "label": ['item', 'private'],
    "values": [1, 2, 4, 5]
  },
  {
    "label": ['item', 'school'],
    "values": [1, 2, 7]
  }
];

И желаемый результат:

var arr = [{
  "label": ["item", "private"],
  "values": [1, 2, 3, 4, 5, 6 ]
}, {
  "label": ["item", "work"],
  "values": [1, 2, 8, 9]
}, {
  "label": ["item", "school"],
  "values": [1, 2, 7]
}]

Вот пример, который находится только наполовину.

var arr = [
  { label: ['item','private'], values: [1,2,3] },
  { label: ['item','private'], values: [1,2,3,6] },
  { label: ['item','work'], values: [1,2,8,9] },
  { label: ['item','private'], values: [1,2,4,5] },
  { label: ['item','school'], values: [1,2,7] }
];

var result = _.unionBy(arr, "label[1]");

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

Есть идеи?

Спасибо Лассе

Ответы [ 3 ]

0 голосов
/ 20 ноября 2018

Вы также можете сделать что-то подобное через lodash :

var arr = [{ "label": ['item', 'private'], "values": [1, 2, 3] }, { "label": ['item', 'private'], "values": [1, 2, 3, 6] }, { "label": ['item', 'work'], "values": [1, 2, 8, 9] }, { "label": ['item', 'private'], "values": [1, 2, 4, 5] }, { "label": ['item', 'school'], "values": [1, 2, 7] } ]

const merge = arr => _.reduce(arr, (r,c) => _.union(r, c.values), [])
const result = _(arr).groupBy('label')
 .entries()
 .reduce((r,[k,v]) => (r.push({ label: k.split(','), values: merge(v) }), r), [])

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Идея состоит в том, чтобы сначала сгруппировать по _.groupBy, а затем получить записи (через _.entries), чтобы вы могли сформировать желаемый вывод с помощью _.reduce._.union мы используем для объединения массивов значений как часть окончательной reduce.

Вот реализация ES6 :

var arr = [{ "label": ['item', 'private'], "values": [1, 2, 3] }, { "label": ['item', 'private'], "values": [1, 2, 3, 6] }, { "label": ['item', 'work'], "values": [1, 2, 8, 9] }, { "label": ['item', 'private'], "values": [1, 2, 4, 5] }, { "label": ['item', 'school'], "values": [1, 2, 7] } ]

const mrg = arr => Array.from(new Set(arr.reduce((r,c) => [...r, ...c.values], [])))
const grp = (arr, k) => arr.reduce((r,c) => (r[c[k]] = [...r[c[k]] || [], c], r), {}) 
const result = Object.entries(grp(arr, 'label'))
  .reduce((r,[k,v]) => (r.push({ label: k.split(','), values: mrg(v) }), r), [])

console.log(result)
0 голосов
/ 21 ноября 2018

Я бы написал:

const arr2 = _(arr)
    .groupBy("label")
    .map(objs => ({
        label: objs[0].label,
        values: _(objs).flatMap("values").uniq().value(),
    }))
    .value()
0 голосов
/ 20 ноября 2018

Не уверен, как это сделать с lodash, но я не думаю, что unionBy - это способ сделать это в любом случае.

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

const arr = [{"label":["item","private"],"values":[1,2,3]},{"label":["item","private"],"values":[1,2,3,6]},{"label":["item","work"],"values":[1,2,8,9]},{"label":["item","private"],"values":[1,2,4,5]},{"label":["item","school"],"values":[1,2,7]}];

console.log(
  Object.values(
    _.groupBy(arr, (item) => item.label.join()),//use lodash group by
  ).map((
    group, //now we have array of array of groups
  ) =>
    group
      .reduce((result, item) => ({
        //reduce a group to one object
        label: result.label, //set label
        values: [
          //set values with unique values of all items
          ...new Set(
            (result.values || []).concat(item.values || []),
          ),
        ],
      })),
  ),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
...