1

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.

5
  • you want to create a object or a array Commented Jan 31, 2020 at 3:24
  • what your desire output from these 3 arrays? Commented Jan 31, 2020 at 3:28
  • object or array is fine. it's a bit confusing since the variables are array but console.log displays it as an object. Commented Jan 31, 2020 at 3:31
  • hmm.. you have no predicate or conditional statements here. Are we assuming three arrays, where first array is a key index and we are correlating by position? Commented Jan 31, 2020 at 3:33
  • @BrettCaswell yes that's it, the first array would act as the key index. Commented Jan 31, 2020 at 3:35

6 Answers 6

4

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

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

5 Comments

Thanks @NickParsons, I tried your solution as well, and it gave me the same result as the selected answer which is simpler for my purpose.
@budji ok, no worries. But I suggest that you change var resultArray = []; to var resultArray = {}; if you're going to use the accepted answer as you really want an object as your output ;)
Using Object.fromEntries is definitely the way to go IMHO, so +1. It's a shame it doesn't provide a function for handling collision.
@customcommander thanks :). I agree, it is a shame it doesn't provide some way to handle collisions, would be a useful feature.
both this answer and @customcommander's answer are intriguing - as I was not familiar with fromEntries method. It's important to note the enumerable nature to using object {} budji. object.key or object[key].
2

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

Comments

1

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

2 Comments

@budji I have rolled back your edit. This isn't what the author of this answer intended. If you think it should be changed, leave a reply here or find a better answer ;)
as an alternative to an array here, you could do an object, var resultObject = Object.assign({});.. same loop for assignment. difference would be type handling on resultObject with enumeration and property accessor support. i.e. resultObject.m or resultObject["m"], and the enumeration for(key in resultObject) resultObject[key]
0
   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.

Comments

0

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

Comments

-1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.