1

If I have an array, what's a simple way of selecting non-consecutive elements? The second and fifth elements for example:

a = ["a","b","c","d","e"]
a.select_elements([1,4]) // should be ["b","e"]

EDIT

I just realized I can do [1,4].map(function(i) {return a[i]}). Is there a less verbose way?

3
  • If you wanted to store them to variables, then in the forthcoming ECMAScript 6 you'll be able to use destructuring assignment var {1:x, 4:y} = a;, which will set the x and y variables to the 1 and 4 members. Commented Aug 31, 2014 at 22:18
  • 1
    If you want something "built in", JavaScript lets you extend native data types using .prototype of the appropriate constructor, so you could write a simple method like: a.grab(1,4) that will return a new Array with those members. Commented Aug 31, 2014 at 22:23
  • 1
    I think the "verbose" way looks good. Hide it in a function if desired (I would avoid mutating the prototype of existing types as I prefer standalone helpers). Commented Aug 31, 2014 at 22:39

4 Answers 4

4

If you're looking for something to make your code look shorter, you could extend Array to have this method:

Array.prototype.select_elements = function(indices) {
    var elements = [];
    for (var i=0; i != indices.length; ++i)
        elements.push(this[indices[i]]);
    return elements;
}

Now you can call the method you want:

a.select_elements([1,4])

["b", "e"]
Sign up to request clarification or add additional context in comments.

2 Comments

Good solution, but I'd probably skip the array and just make it a variadic method by iterating over the arguments object. Though yours matches the code concept in the question.
You can do that, but just be aware the variadic method can cause a stack overflow if you want to select a lot of elements. A single Array argument will not overflow the stack.
3

create a new array, with the elements manually:

var select_elements = [a[1], a[4]];

or create a function that constructs a new array from indices:

function selectElementsWithIndices(sourceArray, selectIndices)
{
    var result = new Array();

    for ( var i = 0; i < selectIndices; i++ ) {
        var index = selectIndices[i];
        result.push(sourceArray[index]);
    }

    return result;
}

var select_elements = selectElementsWithIndices(a, [1, 4]);

Comments

2

You can safely (will not show up in for loops) add a function to all arrays:

Object.defineProperty(Array.prototype, 'get', {
    __proto__: null, 
    value: function() {
        return Array.prototype.slice.call(arguments).map(function(index){ return this[index] }.bind(this)); 
    }
})

Usage:

a = [1, 2, 3, 4, 5, 6];
a.get(1, 4);

Non-variadic version:

Object.defineProperty(Array.prototype, 'get', {
    __proto__: null, 
    value: function(indices) {
        return indices.map(function(index){ return this[index] }.bind(this)); 
    }
})

Usage:

a = [1, 2, 3, 4, 5, 6];
a.get([1, 4]);

Comments

1

There's nothing built in. You can do this:

a.select_elements([a[1], a[4]]);

...which constructs a new array, uses the elements a[1] and a[4], and then passes that to the a.select_elements function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.