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

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.