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 >
    </>
4
  • 2
    Does this answer your question? Split array into chunks Commented Jul 1, 2020 at 8:55
  • Would this help? Commented Jul 1, 2020 at 8: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... Commented Jul 1, 2020 at 9: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. Commented Jul 1, 2020 at 9:18

1 Answer 1

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>

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.