Объединение двухмерного массива в массив объектов с ключами - PullRequest
1 голос
/ 22 апреля 2020

За свою жизнь я не могу этого понять.

Мне нужно взять двумерный массив и создать массив объектов с указанным именем ключа в другом массиве. Как мне go сделать это?

Я пытаюсь вернуть объект, подобный этому:

необходимый результат:

[
  {
    map: 'map-1',
    user: 'user-1',
    type: 'type-1',
    name: 'name-1',
    street: 'street-1' ,
    city: 'city-1'
  },
  {
    map: 'map-2',
    user: 'user-2',
    type: 'type-2',
    name: 'name-2',
    street: 'street-2' ,
    city: 'city-2'
  }
  ...
]

Текущий код:

var collection = [
  ['map-1', 'map-2', 'map-3', 'map-4', 'map-5', 'map-6'],
  ['user-1', 'user-2', 'user-3', 'user-4', 'user-5', 'user-6'],
  ['type-1', 'type-2', 'type-3', 'type-4', 'type-5', 'type-6'],
  ['name-1', 'name-2', 'name-3', 'name-4', 'name-5', 'name-6'],
  ['street-1', 'street-2', 'street-3', 'street-4', 'street-5', 'street-6'],
  ['city-1', 'city-2', 'city-3', 'city-4', 'city-5', 'city-6']
];
var keys = [
  "map", "user", 'type', "name", "street", 'city'
]
const arrayColumn = (arr, n) => arr.map((x, i) => {
  return {[keys[i]]:x[n]}
});

let x = keys.map((x, i)=>{
  return arrayColumn(collection, i)
})
console.log(x)

Ответы [ 4 ]

1 голос
/ 23 апреля 2020

Используйте _.unzip(), чтобы транспонировать коллекцию в строки, а затем отобразить транспонированную коллекцию и объединить каждую строку с ключами с помощью _.zipObject():

const collection = [['map-1', 'map-2', 'map-3', 'map-4', 'map-5', 'map-6'], ['user-1', 'user-2', 'user-3', 'user-4', 'user-5', 'user-6'], ['type-1', 'type-2', 'type-3', 'type-4', 'type-5', 'type-6'], ['name-1', 'name-2', 'name-3', 'name-4', 'name-5', 'name-6'], ['street-1', 'street-2', 'street-3', 'street-4', 'street-5', 'street-6'], ['city-1', 'city-2', 'city-3', 'city-4', 'city-5', 'city-6']];
const keys = ["map", "user", 'type', "name", "street", "city"];

const result = _.unzip(collection).map(o => _.zipObject(keys, o));
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

И та же идея с Lodash / fp - сгенерировать функцию с _.flow(), которая использует _.unzip() для транспонирования коллекции, и отобразить _.zipObject() для преобразования каждой строки в объект:

const fn = keys => _.flow(
  _.unzip,
  _.map(_.zipObject(keys)),
)

const collection = [['map-1', 'map-2', 'map-3', 'map-4', 'map-5', 'map-6'], ['user-1', 'user-2', 'user-3', 'user-4', 'user-5', 'user-6'], ['type-1', 'type-2', 'type-3', 'type-4', 'type-5', 'type-6'], ['name-1', 'name-2', 'name-3', 'name-4', 'name-5', 'name-6'], ['street-1', 'street-2', 'street-3', 'street-4', 'street-5', 'street-6'], ['city-1', 'city-2', 'city-3', 'city-4', 'city-5', 'city-6']];
const keys = ["map", "user", 'type', "name", "street", "city"];

const result = fn(keys)(collection);
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
1 голос
/ 22 апреля 2020

Вы можете уменьшить массив и построить новый объект с требуемыми свойствами.

var collection = [['map-1', 'map-2', 'map-3', 'map-4', 'map-5', 'map-6'], ['user-1', 'user-2', 'user-3', 'user-4', 'user-5', 'user-6'], ['type-1', 'type-2', 'type-3', 'type-4', 'type-5', 'type-6'], ['name-1', 'name-2', 'name-3', 'name-4', 'name-5', 'name-6'], ['street-1', 'street-2', 'street-3', 'street-4', 'street-5', 'street-6'], ['city-1', 'city-2', 'city-3', 'city-4', 'city-5', 'city-6']],
    keys = ["map", "user", 'type', "name", "street", 'city'],
    result = collection.reduce((r, a, i) => {
        a.forEach((v, j) => (r[j] = r[j] || {})[keys[i]] = v);        
        return r;
    }, []);
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 голос
/ 22 апреля 2020

Функции сокращения никогда не легко понять при первом осмотре. Посмотрите на i & j, где они созданы и как они используются.

var collection = [
  ['map-1', 'map-2', 'map-3', 'map-4', 'map-5', 'map-6'],
  ['user-1', 'user-2', 'user-3', 'user-4', 'user-5', 'user-6'],
  ['type-1', 'type-2', 'type-3', 'type-4', 'type-5', 'type-6'],
  ['name-1', 'name-2', 'name-3', 'name-4', 'name-5', 'name-6'],
  ['street-1', 'street-2', 'street-3', 'street-4', 'street-5', 'street-6'],
  ['city-1', 'city-2', 'city-3', 'city-4', 'city-5', 'city-6']
];
var keys = [
  "map", "user", 'type', "name", "street", 'city'
];

// Iterate over lenght of objects in inner array(s)
var result = collection[0].map((_, j) => {
  // For every key, save value in an object under its name with value from collection at position of key index and index of item being created
  return keys.reduce((obj, key, i) => {
    obj[key] = collection[i][j];
    return obj;
  }, {});
});

console.log(result);
0 голосов
/ 22 апреля 2020

var collection = [
  ['map-1', 'map-2', 'map-3', 'map-4', 'map-5', 'map-6'],
  ['user-1', 'user-2', 'user-3', 'user-4', 'user-5', 'user-6'],
  ['type-1', 'type-2', 'type-3', 'type-4', 'type-5', 'type-6'],
  ['name-1', 'name-2', 'name-3', 'name-4', 'name-5', 'name-6'],
  ['street-1', 'street-2', 'street-3', 'street-4', 'street-5', 'street-6'],
  ['city-1', 'city-2', 'city-3', 'city-4', 'city-5', 'city-6']
];
var keys = [
  "map", "user", 'type', "name", "street", 'city'
]



const result = Object
  .entries(collection)
  .reduce((acc, [,x], i) => {
    return x.map((y, j) => ({
      ...acc[j],
      [keys[i]]: y
    }))
  }, []);

console.log(result);
...