AMAK
AMAK

Reputation: 11

Iterate on a range of iterable

I have interface that returns a iterable object. I need to iterate on the first 1000 items of it. What is the best way to combine iterating using Iterator and stop after a certain count is reached.

Thanks

Upvotes: 1

Views: 374

Answers (4)

Carl Manaster
Carl Manaster

Reputation: 40356

Here's a test-driven (Java) wrapper around any existing iterator that should do the trick.

package com.playground;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import junit.framework.TestCase;

public class LimitedIterableTest extends TestCase {

    private static class LimitedIterator<T> implements Iterator<T> {
        private final Iterator<T> original;
        private final int limit;
        private int index = 0;

        public LimitedIterator(Iterator<T> iterator, int limit) {
            this.original = iterator;
            this.limit = limit;
        }

        public boolean hasNext() {
            return index < limit && original.hasNext();
        }

        public T next() {
            index++;
            return original.next();
        }

        public void remove() {
            original.remove();
        }
    }

    private static class LimitedIterable<T> implements Iterable<T> {
        private final int limit;
        private final Iterable<T> original;

        public LimitedIterable(Iterable<T> iterable, int limit) {
            this.original = iterable;
            this.limit = limit;
        }

        public Iterator<T> iterator() {
            return new LimitedIterator<T>(original.iterator(), limit);
        }
    }

    final Integer[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    final List<Integer> list = Arrays.asList(array);

    public void testCount() throws Exception {
        assertEquals(10, count(list));
    }

    public void testLimitedIterable() throws Exception {
        Iterable<Integer> limited = new LimitedIterable<Integer>(list, 5);
        assertEquals(5, count(limited));
        limited = new LimitedIterable<Integer>(list, 50);
        assertEquals(10, count(limited));
    }

    private static <T> int count(Iterable<T> iterable) {
        Iterator<T> iterator = iterable.iterator();
        return count(iterator);
    }

    private static <T> int count(Iterator<T> iterator) {
        int count = 0;
        while (iterator.hasNext()) {
            iterator.next();
            count++;
        }
        return count;
    }
}

Upvotes: 0

Weeble
Weeble

Reputation: 17940

What is your language?

C#:

using System.Linq;
//...
foreach (var item in iface.GetIterable().Take(1000))
{
    //...
}

Python:

import itertools
#...
for item in itertools.islice(iface.get_iterable(), 1000):
    #...

Upvotes: 1

Greg Buehler
Greg Buehler

Reputation: 3894

Make a standard loop that iterates over your collection, but check to see if the index has progress past the target index.

You may want to extract a seperate counter from the main loop index for your specific application.

int stopIndex = 1000;

for (int index = 0; index <= theInterface.Count; index++)
{
    // check to see if we're at/past the stopIndex
    if (index >= stopIndex)
        break;

    // we're still within the conditions, so do something with your interface
    myObjectType localObject = (MyObjectType)theInterface.IndexOf(index);
}

Upvotes: 0

Martin v. L&#246;wis
Martin v. L&#246;wis

Reputation: 127527

I'd use a loop that iterates and have a counter variable incremented; then break out of the loop when the counter reaches 1000.

Upvotes: 1

Related Questions