Array.prototype.take

# Irakli Gozalishvili (13 years ago)

At the moment Array methods can do almost everything that one can do with plain for iteration, only missing piece is break. Is there any chance to get something like:

array.take(predicate)

Although, take would be way more useful if array methods chains were applied lazily. So that:

array.filter(predicate).map(fn).take(once) would only call fn up to a first match.

Maybe Array.prototype.take is not a best fit, but would be great if we could get at least something to cover lack of break.

-- Irakli Gozalishvili Web: www.jeditoolkit.com

# Axel Rauschmayer (13 years ago)

On May 25, 2012, at 2:42 , Irakli Gozalishvili wrote:

At the moment Array methods can do almost everything that one can do with plain for iteration, only missing piece is break. Is there any chance to get something like:

array.take(predicate)

You can use Array.prototype.some for that purpose:

function breakAtEmptyString(strArr) {
    strArr.some(function (elem) {
        if (elem.length === 0) {
            return true; // break
        }
        console.log(elem);
        // implicit: return undefined (interpreted as false)
    });
}

Although, take would be way more useful if array methods chains were applied lazily. So that:

array.filter(predicate).map(fn).take(once) would only call fn up to a first match.

Agreed. The ability to chain iterators would be cool. IIRC, there are plans for a module of iterator tools.

# Irakli Gozalishvili (13 years ago)

Well some returns true or false I was talking more about taking slice of an array. You could obviously do things with an elements in some but it feels very wrong to push them into another array.

-- Irakli Gozalishvili Web: www.jeditoolkit.com

# Axel Rauschmayer (13 years ago)

Sorry. Right. You want a combination of filter and map.

# Strager Neds (13 years ago)

[1,2,3,4,3,2,1].takeWhile((x) => x < 4) => [1,2,3]

correct?

(I use 'takeWhile' here because it is what functional languages use 1; 'take' takes a fixed number of elements from a list.)

This is not the same as map+filter. (I'm not sure how map even would come into play; you're not transforming the data at all.)

Strawman implementation (without TypeErrors), if I understand correctly:

function takeWhile(pred, thisp) { var i; for (i = 0; i < this.length; ++i) { if (i in this) { var continue_ = pred.call(thisp, this[i], i, this); if (!continue_) { // Return all elements before this one. return this.slice(0, i); } } }

return this.slice();  // Clone.

}

If takeWhile is included, it makes sense to me that its complement, dropWhile, should also be included. (Simply replace .slice(0, i) with .slice(i), I think.)

And x.span(a, b) => [x.takeWhile(a, b), x.dropWhile(a, b)] to complete the set.