2

I am having an object as below

[
  {
    assetName: "equity",
    colorCode: "#7C80A2",
    values: [
      { year: "2025", assetValue: 10 },
      { year: "2030", assetValue: 10 },
      { year: "2035", assetValue: 0 },
      { year: "2040", assetValue: 0 },
      { year: "2045", assetValue: 0 },
      { year: "2050", assetValue: 0 },
      { year: "2055", assetValue: 0 },
      { year: "2060", assetValue: 0 }
    ]
  },
  {
    assetName: "fixedIncome",
    colorCode: "#C39936",
    values: [
      { year: "2025", assetValue: 10 },
      { year: "2030", assetValue: 14 },
      { year: "2035", assetValue: 11 },
      { year: "2040", assetValue: 10 },
      { year: "2045", assetValue: 8 },
      { year: "2050", assetValue: 1 },
      { year: "2055", assetValue: 0 },
      { year: "2060", assetValue: 0 }
    ]
  },
  {
    assetName: "opportunistics",
    colorCode: "#5E6873",
    values: [
      { year: "2025", assetValue: 18 },
      { year: "2030", assetValue: 16 },
      { year: "2035", assetValue: 17 },
      { year: "2040", assetValue: 10 },
      { year: "2045", assetValue: 12 },
      { year: "2050", assetValue: 7 },
      { year: "2055", assetValue: 3 },
      { year: "2060", assetValue: 0 }
    ]
  },
  {
    assetName: "assets",
    colorCode: "#5E8987",
    values: [
      { year: "2025", assetValue: 14 },
      { year: "2030", assetValue: 14 },
      { year: "2035", assetValue: 8 },
      { year: "2040", assetValue: 14 },
      { year: "2045", assetValue: 13 },
      { year: "2050", assetValue: 10 },
      { year: "2055", assetValue: 5 },
      { year: "2060", assetValue: 0 }
    ]
  }
];

I want output as below

[
  { year: 2025, equity: 10, fixedIncome: 10, opportunistics: 18, assets: 14 },
  { year: 2030, equity: 10, fixedIncome: 14, opportunistics: 16, assets: 14 },
  { year: 2035, equity: 0, fixedIncome: 11, opportunistics: 17, assets: 8 },
  { year: 2040, equity: 0, fixedIncome: 10, opportunistics: 10, assets: 14 },
  { year: 2045, equity: 0, fixedIncome: 8, opportunistics: 12, assets: 13 },
  { year: 2050, equity: 0, fixedIncome: 1, opportunistics: 7, assets: 10 },
  { year: 2055, equity: 0, fixedIncome: 0, opportunistics: 3, assets: 5 },
  { year: 2060, equity: 0, fixedIncome: 0, opportunistics: 0, assets: 0 }
];

I am trying below code, but not able to get the expected result

function transformData(data) {
  let newData = [];
  for (let i = 0; i < data.length; i++) {
    // data length is 4
    assetNameString = data[i].assetName;
    values = data[i].values;
    for (let j = 0; j < values.length; j++) {
      // values lenght is 8
      newData.push({
        year: values[j].year,
        assetValue: values[j].assetValue
      });
    }
  }
  console.log(newData);
}
transformData(data);

Any help is highly appreciated.

2 Answers 2

2

You could group with an object and collect all values.

var data = [{ assetName: 'equity', colorCode: '#7C80A2', values: [{ year: "2025", assetValue: 10 }, { year: "2030", assetValue: 10 }, { year: "2035", assetValue: 0 }, { year: "2040", assetValue: 0 }, { year: "2045", assetValue: 0 }, { year: "2050", assetValue: 0 }, { year: "2055", assetValue: 0 }, { year: "2060", assetValue: 0 }] }, { assetName: 'fixedIncome', colorCode: '#C39936', values: [{ year: "2025", assetValue: 10 }, { year: "2030", assetValue: 14 }, { year: "2035", assetValue: 11 }, { year: "2040", assetValue: 10 }, { year: "2045", assetValue: 8 }, { year: "2050", assetValue: 1 }, { year: "2055", assetValue: 0 }, { year: "2060", assetValue: 0 }] }, { assetName: 'opportunistics', colorCode: '#5E6873', values: [{ year: "2025", assetValue: 18 }, { year: "2030", assetValue: 16 }, { year: "2035", assetValue: 17 }, { year: "2040", assetValue: 10 }, { year: "2045", assetValue: 12 }, { year: "2050", assetValue: 7 }, { year: "2055", assetValue: 3 }, { year: "2060", assetValue: 0 }] }, { assetName: 'assets', colorCode: '#5E8987', values: [{ year: "2025", assetValue: 14 }, { year: "2030", assetValue: 14 }, { year: "2035", assetValue: 8 }, { year: "2040", assetValue: 14 }, { year: "2045", assetValue: 13 }, { year: "2050", assetValue: 10 }, { year: "2055", assetValue: 5 }, { year: "2060", assetValue: 0 }] }],
    result = Object.values(data.reduce((r, { assetName, values }) => {
        values.forEach(({ year, assetValue }) => 
            (r[year] = r[year] || { year })[assetName] = assetValue
        );
        return r;
    }, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

Comments

1

You've got the right idea, but you need to track the years so you can add to them as you encounter assets. See comments:

function transformData(data) {
    // Use a map to get by-year information
    let yearData = new Map();
    // Loop through the data, using destructuring to get the info we want
    for (const {assetName, values} of data) {
        // Loop through the values array, destructuring again
        for (const {year, assetValue} of values) {
            // Get or add the year entry
            const yearEntry = yearData.get(year) || {year};
            yearData.set(year, yearEntry);
            // Add the asset
            yearEntry[assetName] = assetValue;
        }
    }
    // Get an array of the values
    const newData = [...yearData.values()];
    console.log(newData);
}

Live Example:

const data = [
        { assetName: 'equity', colorCode: '#7C80A2', values: [{ year: "2025", assetValue: 10 }, { year: "2030", assetValue: 10 }, { year: "2035", assetValue: 0 }, { year: "2040", assetValue: 0 }, { year: "2045", assetValue: 0 }, { year: "2050", assetValue: 0 }, { year: "2055", assetValue: 0 }, { year: "2060", assetValue: 0 }] },
        { assetName: 'fixedIncome', colorCode: '#C39936', values: [{ year: "2025", assetValue: 10 }, { year: "2030", assetValue: 14 }, { year: "2035", assetValue: 11 }, { year: "2040", assetValue: 10 }, { year: "2045", assetValue: 8 }, { year: "2050", assetValue: 1 }, { year: "2055", assetValue: 0 }, { year: "2060", assetValue: 0 }] },
        { assetName: 'opportunistics', colorCode: '#5E6873', values: [{ year: "2025", assetValue: 18 }, { year: "2030", assetValue: 16 }, { year: "2035", assetValue: 17 }, { year: "2040", assetValue: 10 }, { year: "2045", assetValue: 12 }, { year: "2050", assetValue: 7 }, { year: "2055", assetValue: 3 }, { year: "2060", assetValue: 0 }] },
        { assetName: 'assets', colorCode: '#5E8987', values: [{ year: "2025", assetValue: 14 }, { year: "2030", assetValue: 14 }, { year: "2035", assetValue: 8 }, { year: "2040", assetValue: 14 }, { year: "2045", assetValue: 13 }, { year: "2050", assetValue: 10 }, { year: "2055", assetValue: 5 }, { year: "2060", assetValue: 0 }] }];

function transformData(data) {
    // Use a map to get by-year information
    let yearData = new Map();
    // Loop through the data, using destructuring to get the info we want
    for (const {assetName, values} of data) {
        // Loop through the values array, destructuring again
        for (const {year, assetValue} of values) {
            // Get or add the year entry
            const yearEntry = yearData.get(year) || {year};
            yearData.set(year, yearEntry);
            // Add the asset
            yearEntry[assetName] = assetValue;
        }
    }
    // Get an array of the values
    const newData = [...yearData.values()];
    console.log(newData);
}

transformData(data);
.as-console-wrapper {
    max-height: 100% !important;
}

Technically, this calls set unnecessarily a lot:

// Get or add the year entry
const yearEntry = yearData.get(year) || {year};
yearData.set(year, yearEntry);

You could do this instead to avoid that if you prefer:

// Get or add the year entry
let yearEntry = yearData.get(year);
if (!yearEntry) {
    yearEntry = {year};
    yearData.set(year, yearEntry);
}

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.