Home > Net >  Javascript: Mapping values from one array to keys within a multidimational array
Javascript: Mapping values from one array to keys within a multidimational array

Time:10-27

I am relatively new to Javascript. I am struggling with data wrangling. I would like to avoid loops.

I need to keep the higher levels of structure of "data_1", but insert an object in place of each of the key values of the form {name: "Key n", length: int}

The objects have of the following structures:

const data_1 = {
  Category1: ["Key A", "Key B", "Key C"],
  Category2: ["Key D", "Key E", "Key F"],
  Category3: ["Key G", "Key H"]
}

const data_2 = {
  "Key A": 100,
  "Key B": 200,
  "Key C": 300,
  "Key D": 400,
  "Key E": 400,
  "Key F": 300,
  "Key G": 200,
  "Key H": 100
}

The target structure should be:

result = {
  Category1: [{name:"Key A", length:100}, {name:"Key B", length:200}, {name: "Key C", length:300}],
  Category2: [{name:"Key D", length:400}, {name:"Key E", length:400}, {name: "Key F", length:300}],
  Category3: [{name:"Key G", length:200}, {name:"Key H", length:100}]
}

I suspect the way to tackle this is something akin to the following pseudo code. I am struggling to define an object as [name: key, length:data_2.key] .

let results = Object.fromEntries(data_1.map(key => [name: key, length:data_2.key]));

Any and all help is appreciated :)

CodePudding user response:

A reduce will do the trick and be quite readable too

const result = Object.entries(data_1).reduce((acc, [key, vals]) => {
  acc[key] = vals.map(val => ({ name: val,length: data_2[val] }));
  return acc;
}, {});
console.log(result);
<script>
const data_1 = {
  Category1: ["Key A", "Key B", "Key C"],
  Category2: ["Key D", "Key E", "Key F"],
  Category3: ["Key G", "Key H"]
}

const data_2 = {
  "Key A": 100,
  "Key B": 200,
  "Key C": 300,
  "Key D": 400,
  "Key E": 400,
  "Key F": 300,
  "Key G": 200,
  "Key H": 100
}</script>

CodePudding user response:

  • Using Object#entries, get list of key-value pairs from data_1
  • Using Array#reduce, iterate over the above while updating the resulting object
    • In each iteration, add the new pair where the value is the list of objects having name and length generated using Array#map. We use the spread operator (...acc) to preserve existing accumulated pairs in every iteration.

const 
  data_1 = { Category1: ["Key A", "Key B", "Key C"], Category2: ["Key D", "Key E", "Key F"], Category3: ["Key G", "Key H"] },
  data_2 = { 'Key A': 100, 'Key B': 200, 'Key C': 300, 'Key D': 400, 'Key E': 400, 'Key F': 300, 'Key G': 200, 'Key H': 100 };

const result = Object.entries(data_1).reduce((acc, [key, names]) => ({
  ...acc,
  [key]: names.map(name => ({ name, length: data_2[name] }))
}), {});

console.log(result);

CodePudding user response:

If we grab the entries, we can map over the keys and get each of them like this. Then we can create an object from the transformed entries.

const data_1 = {
  Category1: ["Key A", "Key B", "Key C"],
  Category2: ["Key D", "Key E", "Key F"],
  Category3: ["Key G", "Key H"]
};

const data_2 = {
  "Key A": 100,
  "Key B": 200,
  "Key C": 300,
  "Key D": 400,
  "Key E": 400,
  "Key F": 300,
  "Key G": 200,
  "Key H": 100
};

const data_3 = Object.fromEntries(
    Object.entries(data_1)
        .map(([cat, keys]) => [cat, keys.map((key) => ({ name: key, length: data_2[key] }))]
    )
);

console.log(data_3);

CodePudding user response:

You can do something like this:

const result = {};

Object.keys(data_1).forEach((key) => {
  const item = data_1[key];
  result[key] = item.map((key) => {
    return { name: key, length: data_2[key] };
  });
});

Either way, seems a bit convoluted to use objects in that manner, when you could maybe use arrays for the data format.

Here's a snippet with a working example:

const data_1 = {
  Category1: ['Key A', 'Key B', 'Key C'],
  Category2: ['Key D', 'Key E', 'Key F'],
  Category3: ['Key G', 'Key H'],
};

const data_2 = {
  'Key A': 100,
  'Key B': 200,
  'Key C': 300,
  'Key D': 400,
  'Key E': 400,
  'Key F': 300,
  'Key G': 200,
  'Key H': 100,
};

const result = {};

Object.keys(data_1).forEach((key) => {
  const item = data_1[key];
  result[key] = item.map((key) => {
    return { name: key, length: data_2[key] };
  });
});

console.log(result);

  • Related