budji
budji

Reputation: 290

How to merge array of keys and arrays of values into an object?

I have the following arrays:

var a = ["F", "M"];
var b = ["female", "male"];
var c = ["fa-female", "fa-male"];

and I am able to assign b to a using for loop with:

ans[a[i]] = values[i]; // { M: "male", F: "female" }

how would I go about adding the third array and assign it to a as well?

{ M: {"male", "fa-male"}, F: {"female", "fa-female"} }

or something similar?

EDIT: Result could either be an array or an object.

Upvotes: 1

Views: 971

Answers (6)

Siva Kondapi Venkata
Siva Kondapi Venkata

Reputation: 11001

Here is one line with forEach. Another way using reduce and Map.

var a = ["F", "M"];
var b = ["female", "male"];
var c = ["fa-female", "fa-male"];

const ans = {};
a.forEach((key, i) => (ans[key] = [b[i], c[i]]));

console.log(ans)

// Alternate way
var ans2 = Object.fromEntries(
  a.reduce((acc, curr, i) => acc.set(curr, [b[i], c[i]]), new Map())
);

console.log(ans2);

Upvotes: 0

customcommander
customcommander

Reputation: 18901

You could combine your arrays to form key/value pairs for Object.fromEntries:

Object.fromEntries([['M', 'male'], ['F', 'female']]);
//=> {M: 'male', F: 'female'}

However Object.fromEntries does not handle collisions:

Object.fromEntries([['M', 'male'], ['F', 'female'], ['F', 'fa-female']]);
//=> {M: 'male', F: 'fa-female'}

As you can see, the previous value for F just got overridden :/

We can build a custom fromEntries function that puts values into arrays:

const fromEntries =
    pairs =>
      pairs.reduce((obj, [k, v]) => ({
        ...obj,
        [k]: k in obj
          ? [].concat(obj[k], v)
          : [v]
      }), {});

fromEntries([['M', 'male'], ['M', 'fa-male'], ['F', 'female'], ['F', 'fa-female']]);
//=> {M: ["male", "fa-male"], F: ["female", "fa-female"]}

How do you create key/value pairs then?

One possible solution: zip

const zip = (x, y) => x.map((v, i) => [v, y[i]]);

zip(['F', 'M'], ['female', 'male']);
//=> [["F", "female"], ["M", "male"]]

So to produce all pairs (and your final object)

fromEntries([
  ...zip(['F', 'M'], ['female', 'male']),
  ...zip(['F', 'M'], ['fa-female', 'fa-male'])
]);

Upvotes: 2

FujiRoyale
FujiRoyale

Reputation: 832

A solution using map and filter

var a = ["M", "F"];
var b = ["female", "male"];
var c = ["fa-female", "fa-male"];

const bAndC = b.concat(c);
let returnObj = {};
a.map(category => {
let catArray = []

if(category === 'F') {
    catArray = bAndC.filter(item => item.includes('female'));
} else {
    catArray = bAndC.filter(item => item.includes('male') && !item.includes('female'));
}
    return returnObj[category] = catArray;
});

Upvotes: -1

tohasanali
tohasanali

Reputation: 934

use this one.

var a = ["F", "M"];
var b = ["female", "male"];
var c = ["fa-female", "fa-male"];

var resultArray = [];
for(var i = 0; i < a.length; i++) {
    resultArray [a[i]] = [b[i], c[i]];
}

Upvotes: 1

Nick Parsons
Nick Parsons

Reputation: 50674

Using Object.fromEntries(), you can build an array of [key, value] pairs by mapping (.map()) each key (ie: value) from a to an array of values from the same index from all the other arrays:

const a = ["F", "M"];
const b = ["female", "male"];
const c = ["fa-female", "fa-male"];

const buildObj = (keys, ...values) => Object.fromEntries(keys.map(
  (key, i) => [key, values.map(arr => arr[i])]
));
  
const res = buildObj(a, b, c);
console.log(res);

Object.fromEntries() has limited browser support, however, it can easily be polyfilled. Alternatively, instead of using an object, you could use a Map, which would remove the need of .fromEntries():

const a = ["F", "M"];
const b = ["female", "male"];
const c = ["fa-female", "fa-male"];

const buildMap = (keys, ...values) => new Map(keys.map(
  (key, i) => [key, values.map(arr => arr[i])]
));
  
const res = buildMap(a, b, c);
console.log("See browser console:", res); // see browser console for output

Upvotes: 4

CRayen
CRayen

Reputation: 579

   var a = ["male","female"];
   var b = ["m","f"];
   var c = ["fa male","fa female"];

   var result = a.reduce((res,val,key) => {
     var temp = [b,c];
     res[val] = temp.map((v) => v[key]);
     return res;
   },{});

This is bit expensive. It is a nested loop.

Upvotes: 0

Related Questions