Преобразовать массив массивов в массив объектов, сгруппированных вместе - PullRequest
0 голосов
/ 04 октября 2018

У меня есть массив массивов.Как мне преобразовать их в массив объектов, сгруппированных вместе?

var abc = [
  ['apple', 'fruit'], ['banana', 'fruit'], ['grapes', 'fruit'], ['red', 'color'], ['blue', 'color'], ['black', 'color']
]


abc = abc.map(function(item) {
  return {
    value: item[0],
    color: item[1]
  }
})

colors = abc.filter(function(item) {
  return item.color === 'color'
})

fruits = abc.filter(function(item) {
  return item.color === 'fruit'
})

var result = [{
  group: 'color',
  value: colors.map(function(item) {
    return item.value
  })
}, {
  group: 'fruit',
  value: fruits.map(function(item) {
    return item.value
  })
}]

console.log(result)

Мой ожидаемый результат:

var abc = [
{
    group: 'color',
    value: ['red', 'blue', 'black']
},
{
    group: 'fruit',
    value: ['apple', 'banana', 'grapes']
}]

Есть ли более простой способ добиться этого?

Я тоже могу использовать lodash.Пожалуйста, сообщите.

Ответы [ 6 ]

0 голосов
/ 04 октября 2018

Подход с одного reduce

var abc = [
  ['apple', 'fruit'],
  ['banana', 'fruit'],
  ['grapes', 'fruit'],
  ['red', 'color'],
  ['blue', 'color'],
  ['black', 'color']
]

var r = abc.reduce((prev, curr) => {
  if(prev.findIndex(p => p.group === curr[1]) === -1) {
    prev = prev.concat({group: curr[1], value: []})
  }
  let idx = prev.findIndex(p => p.group === curr[1])
  prev[idx].value.push( curr[0] )
  return prev;
}, [])

console.log(r)
0 голосов
/ 04 октября 2018

Вот способ сделать это с ES6 Map в качестве промежуточной структуры данных:

var abc = [['apple', 'fruit'],['banana', 'fruit'],['grapes', 'fruit'],['red', 'color'],['blue', 'color'],['black', 'color']];
    
const groups = new Map(abc.map(a =>[a[1], []]));
abc.forEach(a => groups.get(a[1]).push(a[0]));
const result = Array.from(groups, ([group, values]) =>  ({group, values}));

console.log(result);
0 голосов
/ 04 октября 2018

Вы можете создать хештавле, чтобы найти дубликаты дескрипторов:

 const result = [], hash = {};

 for(const [value, group] of abc) {
  if(hash[group]) {
   hash[group].push(value);
  } else {
   result.push({ group, value: (hash[group] = [value]), });
  }
}
0 голосов
/ 04 октября 2018

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

  1. Вы перебираете все элементы и создаете пустой массив
  2. Внутри вашего вновь созданного массива,Вы находите объект, соответствующий group значению
  3. Если он найден, вы расширяете элемент
  4. Если он не найден, вы создаете его

    abc.reduce((arr, input) => {
      const index = arr.findIndex(i => i.group === input[0])
    
      return [
        ...(index > -1
          ? [
            ...arr.slice(0, index),
            {
              group: input[0],
              value: [
                ...arr[index].value,
                input[1]
              ]
            },
            ...arr.slice(index + 1)
          ] : [
            ...arr,
            {
              group: input[0],
              value: [ input[1] ]
            }
          ])
      ]
    }, [])
    
0 голосов
/ 04 октября 2018

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

var data = [['apple', 'fruit'], ['banana', 'fruit'], ['grapes', 'fruit'], ['red', 'color'], ['blue', 'color'], ['black', 'color']],
    result = _(data)
        .groupBy(1)
        .map((array, group) => ({ group, value: _.map(array, 0) }))
        .sortBy('group')
        .value();

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
0 голосов
/ 04 октября 2018

Вот подход с использованием reduce и map.reduce выполняет агрегирование по group, сопоставленному с массивом значений.Object.entries() и map преобразуют эту группировку в нужный формат как массив объектов.

var abc = [
  ['apple', 'fruit'],
  ['banana', 'fruit'],
  ['grapes', 'fruit'],
  ['red', 'color'],
  ['blue', 'color'],
  ['black', 'color']
];

const result = Object.entries(
    abc.reduce((a, e) => {
      if (!(e[1] in a)) {
        a[e[1]] = [];
      }

      a[e[1]].push(e[0]);
      return a;
    }, {})
  ).map(e => ({group: e[0], value: e[1]}))
;

console.log(result);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...