1

I have a huge array of objects, and I want to divide it up to 4 sections so that I could display them much better on my UI.

Here are the array contents, and let's say this contains up to 20 objects, so my goal is to have 4 different arrays that will be containing 5 objects each.

let attributes = [
{
    "FIELDTYPE": "SELECT",
    "ATTRNAME": "Title",
    "ATTRNAMEID": "title",
    "ATTRID": 1
},
{
    "FIELDTYPE": "SELECT",
    "ATTRNAME": "Author",
    "ATTRNAMEID": "author",
    "ATTRID": 2
},
{
    ... //up to 20 more attributes
}
]

I tried to map it like this, but it's not really giving me what I needed

let bookAttributeFields_0;
let bookAttributeFields_1;
let bookAttributeFields_2;
let bookAttributeFields_3;

let bookAttributeFields = attributes.map((attr, i) => {
    switch (i % 4) {
        case 1:
            let fields_1 = {
                name: attr.ATTRNAMEID,
                type: attr.FIELDTYPE,
                label: attr.ATTRNAME
            }
            bookAttributeFields_0 =
                {
                    ...bookAttributeFields_0,
                    fields_1
                }
            break;
        case 2:
            let fields_2 = {
                name: attr.ATTRNAMEID,
                type: attr.FIELDTYPE,
                label: attr.ATTRNAME
            }
             bookAttributeFields_1=
                {
                    ...bookAttributeFields_1,
                    fields_2
                }
             break;
        case 3:
             let fields_3 = {
                name: attr.ATTRNAMEID,
                type: attr.FIELDTYPE,
                label: attr.ATTRNAME
             }
             bookAttributeFields_2=
                {
                    ...bookAttributeFields_2,
                    fields_3
                }
             break;
        case 0:
             let fields_4 = {
                 name: attr.ATTRNAMEID,
                 type: attr.FIELDTYPE,
                 label: attr.ATTRNAME
             }
             bookAttributeFields_3=
                 {
                     ...bookAttributeFields_3,
                     fields_4
                 }
             break;
             default:
                 //nothing
             break;
    }
    return {
        bookAttributeFields_0: bookAttributeFields_0,
        bookAttributeFields_1: bookAttributeFields_1,
        bookAttributeFields_2: bookAttributeFields_2,
        bookAttributeFields_3: bookAttributeFields_3
    }
})

This is how I intend to use the 4 new arrays to be displayed.

return <>
        < Grid container spacing={2} >
            <Grid item xs={3}>
                {data.bookAttributeFields.map((field)=>{
                    return <Fields fields={field.bookAttributeFields_0} />
                })}
            </Grid>
            <Grid item xs={3}>
                {data.bookAttributeFields.map((field)=>{
                    return <Fields fields={field.bookAttributeFields_1} />
                })}
            </Grid>
            <Grid item xs={3}>
                {data.bookAttributeFields.map((field)=>{
                    return <Fields fields={field.bookAttributeFields_2} />
                })}
            </Grid>
            <Grid item xs={3}>
                {data.bookAttributeFields.map((field)=>{
                    return <Fields fields={field.bookAttributeFields_3} />
                })}
            </Grid>
        </Grid >
    </>
G Josh
  • 271
  • 1
  • 5
  • 15
  • 2
    Does this answer your question? [Split array into chunks](https://stackoverflow.com/questions/8495687/split-array-into-chunks) – cbr Jul 01 '20 at 08:55
  • Would [this](https://stackoverflow.com/a/57357024/11299053) help? – Yevhen Horbunkov Jul 01 '20 at 08:58
  • I see, I guess ```slice()``` might help, I don't think I ever used it so not sure. Although for the new array sizes, I'm worried that the exact array size for the new arrays are not fixed, and there would be scenarios where other one array would have 5 objects while others have 4 etc... – G Josh Jul 01 '20 at 09:10
  • If you split your array, you _will_ potentially have resulting array of different size regardless of the method you use to split. No way around it. – Moutah Jul 01 '20 at 09:18

1 Answers1

1

If your intention is to split your input array into chunks of size N and render those as a <Grid /> items, simple implementation of Array.prototype.reduceRight() may do the trick.

const chunkArr = (arr, size) => 
          arr.reduceRight((r,i,_,s) => 
                (r.push(s.splice(0,size)),r),[])

In order to render those deeply nested object properties you will require 3 nested .map() loops: over the outer array, then over the chunk items, then, finally, over object values (fields) of each item.

Following is a quick demo, that illustrates that concept:

const { render } = ReactDOM,
      { Grid } = MaterialUI,
      rootNode = document.getElementById('root')
      
const data = Array.from({length:50},(_,i)=>({FIELDTYPE:`type${i}`,ATTRNAME:`attrname${i}`,ATTRNAMEID:`attrnameid${i}`,ATTRID:i})),
      
      chunkArr = (arr, size) => arr.reduceRight((r,i,_,s) => (r.push(s.splice(0,size)),r),[])

const App = () => {
  const gridItems = chunkArr(data,5)
  return (
    <Grid container>
      {
        gridItems.map((chunk,key) => (
          <Grid container {...{key}}>
            {
              chunk.map((o,key) => (
                <div {...{key}}>
                  {
                    <ul>
                      {
                        Object.values(o).map((field,key) => (
                          <li {...{key}}>{field}</li>
                        ))
                      }
                    </ul>
                  }
                </div>
              ))
            }
          </Grid>
        ))
      }
    </Grid>
  )
}

render (
  <App />,
  rootNode
)
ul {list-style-type:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><script src="https://unpkg.com/@material-ui/core@latest/umd/material-ui.production.min.js"></script><div id="root"></div>
Yevhen Horbunkov
  • 14,965
  • 3
  • 20
  • 42