0

I'm getting some data back from a local API, and unfortunately I don't have much control of the what's coming to me, what I am hoping is that I can transform the data after my API call using a function.

This is what I have currently

transformArray = () => {
    const { rawData } = this.state
    const obj = Object.fromEntries(
      rawData.map(category => [
        category,
        {
          aboveExpectation: rawData[0].value,
          atExpectation: rawData[1].value,
          belowExpectation: rawData[2].value,
        },
        console.log('category', category),
      ]),
    )
    console.log(obj)
  }

Output: [object Object]: {aboveExpectation: 6, atExpectation: 31, belowExpectation: 18}

The rawdata back from the API looks like this

    data [
  {
    "name": "Animal care",
    "Gap": "Above expectation",
    "value": 6
  },
  {
    "name": "Animal care",
    "Gap": "At expectation",
    "value": 31
  },
  {
    "name": "Animal care",
    "Gap": "Below expectation",
    "value": 18
  },
  {
    "name": "Calving and calf rearing",
    "Gap": "Above expectation",
    "value": 8
  },
  {
    "name": "Calving and calf rearing",
    "Gap": "At expectation",
    "value": 29
  },
  {
    "name": "Calving and calf rearing",
    "Gap": "Below expectation",
    "value": 18
  },
  {
    "name": "Reproduction",
    "Gap": "Above expectation",
    "value": 7
  },
  {
    "name": "Reproduction",
    "Gap": "At expectation",
    "value": 25
  },
  {
    "name": "Reproduction",
    "Gap": "Below expectation",
    "value": 23
  }
]

So instead of having 9 separate objects, I would like something that's a bit more iterable, something like this

"Animals": {
    "animalCare": {
      "atExpectation": 1,
      "aboveExpectation": 13,
      "belowExpectation": 15
    },
    "calvingAndCalfRearing": {
      "atExpectation": 1,
      "aboveExpectation": 13,
      "belowExpectation": 15
    },
    "Reproduction": {
      "atExpectation": 1,
      "aboveExpectation": 13,
      "belowExpectation": 15
    }
  },

Now I have made some progress with my transformArray function but it's not quite what I want. I was hoping someone could point me in the right direction please

5
  • Is the raw data you recieve an Array? Commented Dec 9, 2019 at 20:04
  • Yup, it's an array of objects Commented Dec 9, 2019 at 20:05
  • 1
    Please use console.log(JSON.stringify(result, null, 2)) to show data. Copying and pasting from the console does not provide a good view into the objects. Commented Dec 9, 2019 at 20:08
  • copy(JSON.stringify(result, null, 2)) in Chrome's console will copy it directly to the clipboard. Commented Dec 9, 2019 at 20:11
  • Post is updated Commented Dec 9, 2019 at 20:11

1 Answer 1

3

Reduce the array of objects to an object, and create a property for each name, and init/update the value for each Gap:

const data = [{"name":"Animal care","Gap":"Above expectation","value":6},{"name":"Animal care","Gap":"At expectation","value":31},{"name":"Animal care","Gap":"Below expectation","value":18},{"name":"Calving and calf rearing","Gap":"Above expectation","value":8},{"name":"Calving and calf rearing","Gap":"At expectation","value":29},{"name":"Calving and calf rearing","Gap":"Below expectation","value":18},{"name":"Reproduction","Gap":"Above expectation","value":7},{"name":"Reproduction","Gap":"At expectation","value":25},{"name":"Reproduction","Gap":"Below expectation","value":23}]

const result = data.reduce((r, o) => {
  const name = r[o.name] || (r[o.name] = {}) // create an object for the name, or use the existing one
  name[o.Gap] = (name[o.Gap] || 0) + o.value; // add/update the Gap value

  return r
}, {})

console.log(result)

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

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.