Fastest way to get the first n elements of a List or an Array

Which is the fastest way to get the first n elements of a List or an Array? Let’s give a context where we want to extract some first elements from an array or a list. You have a list of students who have taken the final exam. At the end of the school year ceremony, the top ten of best students will be given an award. How do you sort out the list to extract the best students? In this post, I am presenting current support to accomplish this request in some widely used languages.

Introduction to a feasible approach

First and foremost, it needs only a loop to iterate on the first n elements to take them out from the input list or array. Let’s define an input array of String called inArray. The pseudocode of the solution could be illustrated in the following snippet.

int n = 10;
ArrayList outArray = new ArrayList<>();
for (int i = 0; i < n; i++)
  outArray[i] = inArray.get(i);

Depending on which the programming language are you using to implement, there is a bit of slight difference. For example, you can use lambda and closure in Java to implement the solution or use the built-in methods takeor dropin Groovy.

How to implement the solution

Fastest way to get the first n elements of a List or an Array
The fastest way to get the first n elements of a List or an Array

Java

Using a traditional for loop

int n = 10;
ArrayList outArray = new ArrayList<>();
//or: String[] outArray = new String[n];
for (int i = 0; i < n; i++)
  outArray[i] = inArray.get(i);

Using the built-in method subList

String[] out = (String[]) (in.subList(0, n)).toArray();

Using Java 8 Streams

Assumption:

inputList is a list of  <String>. Using Java 8 Streams,

  • to get first N elements from a list into a list,List<String> firstNElementsList = inputList.stream().limit(n).collect(Collectors.toList());
  • to get first N elements from a list into an Array,String[] firstNElementsArray = inputList.stream().limit(n).collect(Collectors.toList()).toArray(new String[n]);

Groovy

When working with List object, we get a lot of nice and useful methods we can use in Groovy. Since Groovy 1.8.1, we can use the methods take() and drop(). With the take() method, we get items from the beginning of the List. We pass the number of items we want as an argument to the method.

To remove items from the beginning of the List we can use the drop() method. Here we pass the number of items we want to drop as an argument to the method. Please keep in mind the original list is not changed, the result of the drop() method is a new list.

def list = ['Simple', 'list', 'with', 5, 'items']
 
assert list.take(1) == ['Simple']
assert list.take(2) == ['Simple', 'list']
assert list.take(0) == []
// Whole list, because we take more items then the size of list
assert list.take(6) == ['Simple', 'list', 'with', 5, 'items']
 
assert list.drop(1) == ['list', 'with', 5, 'items']
assert list.drop(3) == [5, 'items']
assert list.drop(5) == []
assert list.drop(0) == ['Simple', 'list', 'with', 5, 'items']
assert list == ['Simple', 'list', 'with', 5, 'items']
 
// After reading Tim Yates' comment I have added
// more samples showing drop() and take() also work on
// Maps, Iterators, CharSequences and arrays.
def array = ['Rock on!', 'Groovy baby!'] as String[]
assert array.take(1) == ['Rock on!'] as String[]
assert array.drop(1) == ['Groovy baby!'] as String[]
 
def range = 0..10
assert range.take(2) == [0,1]
assert range.take(4) == 0..3
assert range.drop(5) == 5..10
 
def map = [1: 'one', 2: 'two', 3: 'three']
assert map.take(2) == [1: 'one', 2: 'two']
assert map.drop(2) == [3: 'three']
assert map.drop(3) == 
 
def s = 'Hello Groovy world!'
assert s.take(5) == 'Hello'
assert s.drop(6) == 'Groovy world!'

Python

Let’s assume an arbitrary list/array:

in_list = list(range(10))
// Python2: in_list = range(10)
// in_array = [i for i in range(10)]

Slicing the list

n = 5
top5 = in_list[:5]
  • To slice a list, there’s a simple syntax: array[start:stop:step]
  • You can omit any parameter. These are all valid: array[start:]array[:stop]array[::step]

Slicing a generator

Now we introduce an important type of object called a generator, which allows us to generate arbitrarily-many items in a series, without having to store them all in memory at once.

[box type=”note” align=”alignleft” ]Definition: A generator is a special kind of iterator, which stores the instructions for how to generate each of its members, in order, along with its current state of iterations. It generates each member, one at a time, only as it is requested via iteration.[/box]

import itertools
top5 = itertools.islice(in_list, 5) # grab the first five elements
  • You can’t slice a generator directly in Python. itertools.islice() will wrap an object in a new slicing generator using the syntax itertools.islice(generator, start, stop, step)
  • Remember, slicing a generator will exhaust it partially. If you want to keep the entire generator intact, perhaps turn it into a tuple or list first, like: result = tuple(generator).

JavaScript

To get the first n elements of an array, use myArray.slice(0, n);.

For example: take three elements from the list

var size = 3;
var items = list.slice(0, size).map(i => {
    return <myview item={i} key={i.id} />
}

Summary

From my perspective, this operation is often requested in real applications. Beware of existing solutions is probably useful and necessary because we could need either of them in your coming projects.

References

  1. The fastest ways to get the first n elements of a List into an Array accessed on 20/05/2020
  2. Groovy Goodness: Take and Drop Items from a List, accessed on 20/05/2020
  3. How to take the first N items from a generator or list in Python? accessed on 28/05/2020
  4. Generators & Comprehension Expressions, accessed on 28/05/2020

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.