1

For the life of me I cannot figure this out.

I need to take a 2 dimensional array and create an array of objects with a specified keyname in another array. How would I go about doing this?

I'm trying return an object like this:

needed result:

[
  {
    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'
  }
  ...
]

Current code:

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)
0

4 Answers 4

1

Use _.unzip() to transpose the collection to rows, and then map the transposed collection, and combine each row with the keys via _.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>

And the same idea with Lodash/fp - generate a function with _.flow(), that uses _.unzip() to transpose the collection, and map with _.zipObject() to convert each row to an object:

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>

Sign up to request clarification or add additional context in comments.

Comments

1

Reduce functions are never easy to understand upon first inspection. Look at the i & j, where they are created and how are they used.

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);

Comments

1

You could reduce the array and build new object with the wanted properties.

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; }

Comments

0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.