1

Given an even length array, I am trying to find a clean method using React to put half an array in one div tag and inside it, each element should be in a span tag, and the same for the other half. For example, given the array of numbers 1 to 6, the rendered output should be:

<div>
    <span>1</span>
    <span>2</span>
    <span>3</span>
</div>
<div>
    <span>4</span>
    <span>5</span>
    <span>6</span>
</div>

The main problem is dealing with the JSX combined with the JS, I can't figure how to achieve this result since some inner loop seems to must be used and it interferes with the returned rendered JSX.

I will also need this to be extended to do similar functionality with splitting the array to different amount of <div> tags, e.g. 3 <div> tags with 2 <span> tags in each.

How can we achieve this in a clean manner?

2
  • 1
    have a look here stackoverflow.com/questions/8495687/split-array-into-chunks for chunking your array of data into smaller chunks, and use a nested map to render your chunks. If is specifically half the array each time, you could use array slice using half the length of the array. It would also be good to see what you have tried specifically Commented Dec 23, 2020 at 13:27
  • If this is a layout issue, maybe look into using CSS Grids instead so you don't need to manually split things into divs. Commented Dec 23, 2020 at 13:37

3 Answers 3

1

You can use _.chunk() of lodash to split array:

const array = [1, 2, 3, 4, 5, 6];
const n=2;

render() {
    return _.chunk(array, [size=n]).map(subArray => <div>{subArray.map(i => <span>i</span>}</div>);
}
Sign up to request clarification or add additional context in comments.

Comments

1

You can do it like this:

const arr = [1, 2, 3, 4, 5, 6];
.....

// Inside some JSX components render method
{[arr.slice(0, arr.length / equalParts),
  arr.slice(arr.length / equalParts - 1, arr.length)].map(
  (half, index) => (
    <div key={`outer_${index}`}>
      {half.map((item, index) => (
        <span key={`inner_${index}`}>{item}</span>
      ))}
    </div>
  ),
)}

For the second part of the question you can extract it to a function:

const splitAndRender = (arr: number[], equalParts: number) => {
  const slices = [];

  const innerLength = arr.length / equalParts;

  for (let i = 0; i < equalParts; i++) {
    slices.push(arr.slice(i * innerLength, (i + 1) * innerLength));
  }

  return slices.map((half, index) => (
    <div key={`outer_${index}`}>
      {half.map((item, index) => (
        <span key={`inner_${index}`}>{item}</span>
      ))}
    </div>
  ));
};

and use the function like:

const arr = [1, 2, 3, 4, 5, 6];
.....

{splitAndRender(arr, 3)}

1 Comment

arr.splice() modifies arr – it doesn't sound like something you'd want to use in a render method.
1

in React needs to close tags inline so i found just this (not so performant) way:

const TMP = ({data,splitby}) => {
  let transformedData = data.reduce((r,v,i)=>{
    if (i%splitby)
      r[r.length-1].push(v)
    else r.push([v]);
    return r
  },[])

  return <div>
     {
       transformedData.map((v,index)=>(
         <div key={`div-$index`}>
           {
             v.map((s,idx)=> <span key={`div-${index}-span-${idx}`}>{s}</span>)
           }
         </div>
        ))
     }
  </div>
};

ReactDOM.render(
  <TMP data={Array.from({length: 25}, (v, i) => i)} splitby={3}/>,
  document.getElementById("tmp_root")
);
div {
  border: 1px solid tomato;
}

span {
  display: block;
  border:1px solid silver;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


<div id="tmp_root"></div>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.