2

I have an object like this:

let inputData = {
  "dimensions": [
    {
      "id": "dimension_re",
      "label": "Region",
      "values": ["East", "East", "West", "SouthWest", "South","NorthEast"]
    }, 
    {
      "id": "dimension_cnt",
      "label": "County",
      "values": ["London", "Italy", "Germany", "US", "Russia","India"]
    },
    {
      "id": "measure_sales",
      "label": "Sales",
      "values": [100, 156, 432, 462, 25,100]
    }, 
    {
      "id": "measure_qty",
      "label": "Quantity",
      "values": [85, 34, 153, 434, 52, 43]
    }, 
    {
      "id": "measure_profit",
      "label": "Profit",
      "values": [123, 45, 421, 465, 451, 56]
    }
  ]
}

My expected output:

let expectdData = [
  {
    "Region": "East",
    "County": "London",
    "Sales": 100,
    "Quantity": 85,
    "Profit": 123
  }, 
  {
    "Region": "East",
    "County": "Italy",
    "Sales": 156,
    "Quantity": 34,
    "Profit": 45
  }, 
  {
    "Region": "West",
    "County": "Germany",
    "Sales": 432,
    "Quantity": 153,
    "Profit": 421
  }, 
  {
    "Region": "SouthWest",
    "County": "US",
    "Sales": 462,
    "Quantity": 434,
    "Profit": 465
  }, 
  {
    "Region": "South",
    "County": "Russia",
    "Sales": 25,
    "Quantity": 52,
    "Profit": 451
  },
  {
    "Region": "NorthEast",
    "County": "India",
    "Sales": 100,
    "Quantity": 43,
    "Profit": 56
  }
]

Here is my program to get this expected data:

let actualData = [];

inputData.dimensions.forEach((e,i) => {
  let tempVal = e.label;
  e.values.forEach((elem,index) => {
    actualData[index] = new Object({
      [tempVal] : elem
    });
  })
});

console.log(actualData);

But unfortunately, I only get the last item for every object. In my console it looks like this:

[
  { Profit: 123 },
  { Profit: 45 },
  { Profit: 421 },
  { Profit: 465 },
  { Profit: 451 },
  { Profit: 56 }
]

I think, in every iteration, it just overrides the "tempVal" variable. How to prevent this & how can I achieve the expected array of objects?

3 Answers 3

1

You are replacing the whole object on each iteration, you just need to create it if it does not exists, otherwise you can replace the key.

let actualData = [];

inputData.dimensions.forEach((e,i)=>{
  let tempVal = e.label;
  e.values.forEach((elem,index) => {
    if (!actualData[index]) {
      actualData[index] = {}
    }
    actualData[index][tempVal] = elem
  })
});

console.log(actualData);
Sign up to request clarification or add additional context in comments.

Comments

1
  • Using Array#reduce, iterate over dimension while updating a list of the resulting objects
  • In each iteration, use Array#forEach to iterate over the current values list and update the object at each index with label as key and the current value as value

const inputData = {
  "dimensions": [
    {
      "id": "dimension_re",
      "label": "Region",
      "values": ["East", "East", "West", "SouthWest", "South","NorthEast"]
    }, 
    {
      "id": "dimension_cnt",
      "label": "County",
      "values": ["London", "Italy", "Germany", "US", "Russia","India"]
    },
    {
      "id": "measure_sales",
      "label": "Sales",
      "values": [100, 156, 432, 462, 25,100]
    }, 
    {
      "id": "measure_qty",
      "label": "Quantity",
      "values": [85, 34, 153, 434, 52, 43]
    }, 
    {
      "id": "measure_profit",
      "label": "Profit",
      "values": [123, 45, 421, 465, 451, 56]
    }
  ]
};

const res = inputData.dimensions.reduce((acc, { label, values = [] }) => {
  values.forEach((value, index) => {
    acc[index] = { ...(acc[index] ?? {}), [label]: value };
  });
  return acc;
}, []);

console.log(res);

1 Comment

Great ! Actually I didn't know the reduce method that much, But your answer gives me a clear idea about that. thank you
1

Since your index comes from the inner loop, you'll be replacing the values at actualData[index] each outer loop iteration, that's why you only end up with the last.

Try this reduce operation instead...

const inputData = {"dimensions":[{"id":"dimension_re","label":"Region","values":["East","East","West","SouthWest","South","NorthEast"]},{"id":"dimension_cnt","label":"County","values":["London","Italy","Germany","US","Russia","India"]},{"id":"measure_sales","label":"Sales","values":[100,156,432,462,25,100]},{"id":"measure_qty","label":"Quantity","values":[85,34,153,434,52,43]},{"id":"measure_profit","label":"Profit","values":[123,45,421,465,451,56]}]};

// Find the max number of `values`
const maxLength = Math.max(...inputData.dimensions.map(({ values }) => values.length));

const actualData = inputData.dimensions.reduce(
  (arr, { label, values }) =>
    arr.map((obj, i) => ({ ...obj, [label]: values[i] })),
  Array.from(
    {
      length: maxLength,
    },
    () => ({}) // creates an array of empty objects
  )
);
  
console.log(actualData);
.as-console-wrapper { max-height: 100% !important; }

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.