简体   繁体   中英

Creating an object from API data and adding it to an array dynamically

I have a data set that I'm pulling in from a database. It's one dimensional and I basically need to make it more structured. I refer to it as "flat".

I need to display a heading, and items under that heading that are related to the heading.

The data comes in as having and section_name (the heading) and item_name (items) and other data unique to each item like download URLs etc.

  1. item_name(item)_______section_name(header)
  2. first_________________Funds
  3. second________________Funds
  4. third_________________Funds
  5. fourth________________Literature
  6. fifth_________________Literature
  7. sixth_________________Literature
  8. seventh_______________Literature
  9. eighth________________DueDilligence

I don't know what any of the names will be for the items or sections, or how many items, sections, or items per section. As I said, it's very flat. This needs to be fully dynamic which is why this is complicating things for me.

Here is what I've done.

  1. API call to retrieve data. Store data in a state as an array (it comes in as an array of objects).
  2. I create an empty array to store my newly structured data.
  3. I loop through the data with a foreach.
  4. I create a new object for my new data to add to the new array so I can loop over it later.
  5. I first check to make sure the data exists.
  6. To create the headers I check to see if my new empty array is actually empty OR my section_name is not the same as the last one.(in the original data array I got from the API call)
  7. I store the section_names as an object in the new array (newArray.push(newObject)

I've gotten this far. Now I need to take the item_names that correlates to the section_names and store them in the object under each header name, or at least in the same index.

 _generateInfo() { 

        let dataArray = this.state.stepTwoData
        let newArray =[]

        dataArray.forEach(function(item, index) {
            let newObject = {}
            if (index > 0) {
                if (newArray.length === 0 || item.investor_portal_section_name !== dataArray[index -1].investor_portal_section_name) {
                    newObject["name"] = item.investor_portal_section_name
                    newObject["items"] = []
                    newArray.push(newObject)
            } 

        })
        console.log(newArray)
    }

I tried pushing the items to the "number" array on my new object and that doesn't seem to work properly. Sometimes it will duplicate my newObject.name

Checking if the newObject.name === the section_names in the array and push it to the "number" array in my new object just creates new key-value pairs so it's still not correlating.

I tried looping through again in the if statement and if section_name === newObject.name then create a newObject and push it, but it would only push one of the items repeatedly instead of going through all of them.

I need to loop through and create a header (one header per different section_name). Then add each item that corresponds to the section_name to it. like this

[
{section_name(header): "Funds",
items: [
 {
  name: item_name,
  sku: item_sku,
  url: item_url
},
{
 name: item_name,
 sku: item_sku,
 url: item_url
}]
},
{section_name(header):"Literature",
items: [
 {name: item_name,
  sku: item_sku,
  url: item_url
},
{
 name: item_name,
 sku: item_sku,
 url: item_url
}]}
]

Using associative array (dictionary) to segregate you data itmes by categories will do the job. I've drafted some POC code that illustrates the idea. The key element there is buildAssociativeArray function

const raw_data = [
    {item_name: "first", section_name: "Funds"}, 
    {item_name: "second", section_name: "Funds"}, 
    {item_name: "third", section_name: "Funds"}, 
    {item_name: "fourth", section_name: "Literature"}, 
    {item_name: "fifth", section_name: "Literature"}, 
    {item_name: "sixth", section_name: "Literature"}, 
    {item_name: "seventh", section_name: "Literature"}, 
    {item_name: "eighth", section_name: "DueDilligence"}, 
]

function buildAssociativeArray(data) {
    const dictionary = {};
    for (var i = 0; i < data.length; i++) {
        const item = data[i];
        const section = item.section_name;
        var dictEntry = dictionary[section];
        if (!dictEntry) {
            dictEntry = [];
            dictionary[section] = dictEntry;
        }
        dictEntry.push({
            name: item.item_name,
            //    other fields like sku: item_sku or url: item_url may follow here
        });
    }
    return dictionary;
}

const dictionary = buildAssociativeArray(raw_data);
console.log(dictionary);
/*
At this point
dictionary == {
  "Funds": [
    {
      "name": "first"
    },
    {
      "name": "second"
    },
    {
      "name": "third"
    }
  ],
  "Literature": [
    {
      "name": "fourth"
    },
    {
      "name": "fifth"
    },
    {
      "name": "sixth"
    },
    {
      "name": "seventh"
    }
  ],
  "DueDilligence": [
    {
      "name": "eighth"
    }
  ]
}
*/

//    Associcative array dictionary itself allows to further solve you task using for (var key in dictionary) {...} operator
//    If however you need to obtain the data structure looking exactly like the one in your question you may go further with following function

function transformAssociativeArray(dictionary) {
    const array = [];
    for (var key in dictionary) {
        const items = dictionary[key];
        const newEntry = {
            section_name: key,
            items: items,
        }
        array.push(newEntry);
    }
    return array;
}

const array = transformAssociativeArray(dictionary);
console.log(array);
/*

At this point
array == [
  {
    "section_name": "Funds",
    "items": [
      {
        "name": "first"
      },
      {
        "name": "second"
      },
      {
        "name": "third"
      }
    ]
  },
  {
    "section_name": "Literature",
    "items": [
      {
        "name": "fourth"
      },
      {
        "name": "fifth"
      },
      {
        "name": "sixth"
      },
      {
        "name": "seventh"
      }
    ]
  },
  {
    "section_name": "DueDilligence",
    "items": [
      {
        "name": "eighth"
      }
    ]
  }
]
*/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM