'Is it possible to map only a portion of an array? (Array.map())

I am building a project using React.js as a front-end framework. On one particular page I am displaying a full data set to the user. I have an Array which contains this full data set. It is an array of JSON objects. In terms of presenting this data to the user, I currently have it displaying the whole data set by returning each item of data using Array.map().

This is a step in the right direction, but now I need to display only a portion of the data-set, not the whole thing, I also want some control in terms of knowing how much of the total data set has been displayed, and how much of the data set is yet to be displayed. Basically I am building something like a "view more" button that loads more items of data to the user.

Here is what I am using now where 'feed' represents my Array of JSON objects. (this displays the whole data set.)

 return (
  <div className={feedClass}>
  {
    feed.map((item, index) => {
      return <FeedItem key={index} data={item}/>
    })
  }
  </div>
);

I am wondering if it is possible to use .map() on only a portion of the array without having to break up the array before hand? I know that a possible solution would be to hold the full data set, and break it off into portions, and then .map() those portions, but is there a way to .map() a portion of the array without having to break it up?

Any and all feedback is appreciated. Thanks!



Solution 1:[1]

Do not try to solve this problem with a hack in your mapping step.

Instead, slice() the list to the right length first before the mapping:

class Feed extends React.Component {
  constructor(props) {
    super(props)
    
    this.handleShowMore = this.handleShowMore.bind(this)
    
    this.state = {
      items: ['Item A', 'Item B', 'Item C', 'Item D'],
      showItems: 2
    }
  }
  
  handleShowMore() {
    this.setState({
      showItems: 
        this.state.showItems >= this.state.items.length ?
          this.state.showItems : this.state.showItems + 1
    })
  }
  
  render() {
    const items = this.state.items.slice(0, this.state.showItems).map(
      (item) => <div>{item}</div>
    )
    
    return (
      <div>
        {items}
        <button onClick={this.handleShowMore}>
          Show more!
        </button>
      </div>
    )
  }
}
  
ReactDOM.render(
  <Feed />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='root'></div>

Solution 2:[2]

The easiest way in my head is just to use a filter and map

const feed = [1,2,3,4,5,6,7,8,9,10,11]
feed.filter((item, index) => index < 5).map((filteredItem) => //do somthing with filtred item here//)

where 5 is just a number of items you want to get

Solution 3:[3]

you could use the slice function before to map the array, it looks like you want to do some pagination there.

var fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'];
var citrus = fruits.slice(1, 3);

// fruits contains ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']
// citrus contains ['Orange','Lemon']

Solution 4:[4]

Array.reduce should do what you're asking for. Just change the if statement depending on which range you want.

var excludeAfterIndex = 5;

feed.reduce((mappedArray, item, index) => {
  if (index > excludeAfterIndex) { // Whatever range condition you want
    mappedArray.push(<FeedItem key={index} data={item}/>);
  }

  return mappedArray;
}, []);

Solution 5:[5]

If you just want to map a portion of an array, you should first filter() your array to obtain the expected portion according to conditions :

array.filter(item => <condition>).map();

Solution 6:[6]

Yes, you can map portion of array, based on index. For example:

yourArray = yourArray.map(function (element, index, array) {
        if (array.indexOf(element) < yourIndex) {
            return {
               //logic here
            };
        } else {
            return {
                //logic here
            };
        }

    });

Solution 7:[7]

Array#map iterates over all items.

The map() method creates a new array with the results of calling a provided function on every element in this array.

You could use Array#filter

The filter() method creates a new array with all elements that pass the test implemented by the provided function.

for the wanted items and then apply map for the wanted format.

Solution 8:[8]

There is no version of the map() function that only maps a partial of the array.

You could use .map() in conjunction with .filter().

You get the index of the current element as the second arg of map and if you have a variable for current page and page size you can quite easily filter the right page from your array without having to really slice it up.

var currentPage = 1;
var pageSize = 25;

dataArray.filter(function(elt, index) {

    var upperThreshold = currentPage * pageSize;
    var lowerThreshold = currentPage * pageSize - pageSize;

    return index < upperThreshold && index > lowerThreshold;

});

Solution 9:[9]

Using slice() is better than adding a condition to your map or reduce function, but it still creates an additional, unused copy of that segment of the array. Depending on what you're doing, that might not be desired. Instead, just use a custom map function:

function sliceMap(fn, from, toExclusive, array) {
  const len = toExclusive - from;
  const mapped = Array(len);

  for (let i = 0; i < len; i++) {
    mapped[i] = fn(array[i + from], i);
  }

  return mapped;
};

Note that fn receives the array value and the (now) zero-based index. You might want to pass the original index (i + from). You might also want to pass the full array as a third parameter, which is what Array.map does.

Solution 10:[10]

Use this, easy approach

const [limit, setLimit] = useState(false);
const data = [{name: "john}, {name: 'Anna'}]

Here we will have 2 cases:

  1. Display only first data which is John
  2. Display all
data.slice(0, extended ? data.length : 1).map((item, index) => <Text>{item.name}</Text>)

....

Solution 11:[11]

You can use slice to get portion of an array:

const data = [1,2,3,4,5,6,7,8,9,10,11]

var updatedData = data.slice(0, 3);