6

I'm using a javascript library which returns arrays not starting from zero like starting from 26 or 1500, what i want to do is a method to get the first element in that array regardless of the index number starting with 0 or any other number.

Are they any method to do this in javascript ?

2
  • 2
    What is that javascript library? what have you tried so far? examples of your code please. Commented Jun 23, 2016 at 11:53
  • if you don't care about undefined or other "null-ish" values, you can go with const [first] = array.filter(Boolean) Commented Apr 18, 2024 at 10:34

6 Answers 6

7

I suggest to use Array#some. You get the first nonsparse element and the index. The iteration stops immediately if you return true in the callback:

var a = [, , 22, 33],
    value,
    index;

a.some(function (v, i) {
    value = v;
    index = i;
    return true;
});

console.log(index, value);

Sign up to request clarification or add additional context in comments.

1 Comment

@T.J.Crowder, it works, btw with undefined values as well.
2

The information below is generally useful, but for the problem the OP listed, Nina's answer is by far a better solution.


Those are called sparse arrays and they're one of the few situations where you may want to use for-in on an array.

Remember that arrays are objects in JavaScript, and array entries are properties keyed by names (array indexes) that meet certain criteria. So we can use the features that let us discover the properties on an object to find the indexes on your sparse array.

for-in example:

for (var n in theArray) {
    if (theArray.hasOwnProperty(n) && isArrayIndex(n)) {
        // Use theArray[n]
    }
}

This answer shows how you can determine that n is an array index as opposed to being some other property. A very technical definition would be

function isArrayIndex(n) {
    return /^0$|^[1-9]\d*$/.test(n) &&
           n <= 4294967294;
}

...but a definition that's good enough for most of us would be

function isArrayIndex(n) {
    return !isNaN(parseInt(n, 10));
}

Similarly, you can use Object.keys; since it only looks at own enumerable properties, you don't need the hasOwnProperty check:

Object.keys(theArray).forEach(function(n) {
    if (isArrayIndex(n)) {
        // ...
    }
});

Note that officially, neither of those is in any particular order, not even in ES2015 ("ES6"). So in theory, you could see the indexes out of numeric order. In the real world, I've never seen an even vaguely-modern JavaScript engine that returned array indexes out of order. They're not required to, but every one I've tried does.

So officially, you would need to get a full list and then find the minimum value in it:

var min = Object.keys(theArray).reduce(function(min, n) {
    var i = parseInt(n, 10);
    return isNaN(i) || (min !== undefined && min > i) ? min : i;
}, undefined);

That'll given you undefined if the array is empty, or the min index if it isn't. But if you want to make the assumption you'll get the keys in numeric order:

// Makes an assumption that may not be true
var min = +Object.keys(theArray).filter(isArrayIndex)[0];

If you're using a JavaScript engine that's entirely up-to-date, you can rely on the order returned by Object.getOwnPropertyNames, which is required to list the array indexes in order.

var min = +Object.getOwnPropertyNames(theArray).filter(isArrayIndex)[0];

Comments

1

It may be useful to use a filter function on the array to get back a normalised array.

var fullArray = array.filter(function(n){
    return n != undefined;
});
fullArray[0]

The answers here may help you decide Remove empty elements from an array in Javascript

2 Comments

you lose the index, if that is important.
Actually, that filters out two completely different things: Missing entries (because filter doesn't visit those at all), and entries that are present but have the value undefined. If you just want to filter out missing entries, var fullArray = array.filter(function() { return true; });
1

I guess one alternative to Array.prototype.some() is the Array.prototype.findIndex() method. These are much faster than filter alone and will keep your array and indices untouched.

var arr = new Array(1000),
     fi = -1;
arr[777] = 1453; // now we have a nice sparse array
fi = arr.findIndex(f => f !== void 0); // void 0 is the perfect undefined
console.log(fi);
console.log(arr[fi]);

13 Comments

This requires a lot more calls to the callback than Nina's Array#some (because findIndex visits sparse elements), and your condition filters out entries that are present but have the value undefined, not just missing entries.
@T.J. Crowder : "because findIndex visits sparse elements" No it does not and it would be very pointless if it did. Please read first paragraph. developer.mozilla.org/tr/docs/Web/JavaScript/Reference/…
Do you really think I'd say that if I weren't sure? If I hadn't checked? I checked the spec and proved it experimentally before commenting. jsfiddle.net/hwk7fuah I'm sorry MDN mislead you, I hate when that happens, but you might have taken the time to give it a quick test before being snarky. :-) MDN is extremely good most of the time, but it is community-edited and sometimes clangers like that one make their way in. I've fixed it.
@T.J. Crowder : OK sorry for sounding snarly. Apologies. But there is this; a = new Array(1000) doesn't produce any indices and a[777] = 9 produces only "1" index key (property of array object) as 777. Check with a for in loop you will get only one property. So no array method including findIndex can not visit not existing properties even if they wanted to. We need fill() first. But most importantly findIndex & indexOf are two of the best optimized tools in JS. Please check a comparison of findIndex and some on 1M items sparse array in this fiddle jsfiddle.net/hwk7fuah/2
"Check with a for in loop you will get only one property." Yes, I know how sparse arrays work. "So no array method including findIndex can not visit not existing properties even if they wanted to." Sure they can, and many do: Look at Array#some, it doesn't visit nonexistant entries. Neither does forEach. Or filter. Or map. find and findIndex are exceptions to the general rule.
|
1
const arr = [0,1,2]

// using destructuring to get the first element

let [first] = arr

// plus: using destructuring to get the last element

let [first] = [...arr].reverse()

Comments

0

With this piece of code you can find first assigned value index and then get the value from your array:

var a = [, , 22, 33];
var value = a.find((v, i) => i in a);
console.log(value);
/* ---------------------------------------------- */
var i = 0
while (!(i in a) && i < a.length) i++; // If i === a.length then the array is emtpy
console.info(i, a[i]);

First implementation uses Array.prototype.find which makes less variable usage so this is cleaner but to find the index you should call indexOf over the array.

But the second one is a little bit old fashioned but give the chance of having index without extra efforts.


BTW Nina's seems better. (can make it shorter?)

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.