7

I want to ask a question that I have about a 2D array in JavaScript, similar to this:

var array = [[2,45],[3,56],[5,67],[8,98],[6,89],[9,89],[5,67]]

That is, on every index, I have an array as well.

Suppose that I have a value in my second index like 56, and I want the corresponding 1st index (i.e. 3 in above example).

I can do it using a loop (if no other option), but is there any better way?

Also, I know indexOf method in JavaScript, but it's not returning the index when I call it like this:

array.indexOf(56);

Any insight will be helpful.

5 Answers 5

14

Use some iterator function.

filter allows you to iterate over an array and returns only the values when the function returns true.

Modern browsers way:

var arr = array.filter( function( el ) {
    return !!~el.indexOf( 56 );
} );
console.log( arr ); // [3, 56]
console.log( arr[ 0 ] ); // "3"

Legacy browsers way, using jQuery:

var arr = $.filter( array, function() {
    return !!~$.inArray( 56, $( this ) );
} );
console.log( arr ); // [3, 56]
console.log( arr[ 0 ] ); // "3"
Sign up to request clarification or add additional context in comments.

3 Comments

For legacy browsers, use a for loop, not $.filter
What does !!~ do? (I'm new to JS and have never seen it before!)
@Tom If the indexOf returns 0 (the first element in the array) it will still fire true as ~ turns 0 into -1 the first ! turns -1 into a boolean value false and the second ! turns the false value into true. Steps shown here.
6

You could do like this:

var ret;
var index = array.map(function(el){return el[1];}).indexOf(56);
if (index !== -1) {
  ret = array[index][0];
}

5 Comments

indexOf is not supported by all browsers either :-)
@FlorianMargaine Yep, that's it, so if op use .indexOf, he just could use Array.map.
I don't really get your solution however. You're just returning a new array with the second value of the inner arrays, but OP wants the first value. For example, he wants "3" back in this case.
@FlorianMargaine I missed that, thought he wanted the index.
No problem :-) I prefer my answer though :(
1

array.indexOf( x ) returns the position of x in the array, or -1 if it is not found. In your 2D array this is useless, since 56 isn't in array; it is in an array which is contained in array.

You will have to loop over the first array, then use indexOf to check each sub-array.

1 Comment

Alternatively, if you have flexibility with the data structure, the feature you are emulating is that of a dictionary. Consider switching to a javascript associative array: {3:56, 2:45, 5:67,...}
1

I found that in IE6 at least (I'm not sure about the more recent versions), the built-in Array type didn't have an indexOf method. If you're testing in IE, perhaps that's why you couldn't get started. I wrote this little addition to include in all my code:

if(!Array.prototype.indexOf){
    Array.prototype.indexOf = function(obj){
        for(var i=0; i<this.length; i++){
            if(this[i]===obj){
                return i;
            }
        }
     return -1;
   };
}

I can't really take credit for this. It's probably a fairly generic piece of code I found in some tutorial or one of Doug Crockford's articles. I'm quite sure someone will come along with a better way of writing it.

I find working in Firefox is a good place to start because you can install the Firebug console and get a better idea where things are going wrong. I admit that doesn't solve cross-browser problems, but at least it allows you to get a start on your project.

This little piece of code will ensure you can use the indexOf method to find where a given value is in a one-dimensional array. With your 2-dimensional array, each element in the outer array is an array not a single value. I'm going to do a little test to see exactly how that works and get back to you, unless someone else comes in with a better answer.

I hope this at least gets you started.

UPDATE Assuming you have a browser that implements Array.indexOf, I've tried every which way to pass one of the array elements in your outer array.

alert(array.indexOf([3,56]))
alert(array.indexOf("3,56"))

just return -1.

Oddly,

alert(array.indexOf(array[1]))

correctly returns 1. But you need to know the index of the inner array to get the index! I can't see a way of passing an array to the indexOf method.

1 Comment

I was going to mention this. I've been in positions in the past where I've been tearing my hair out over this. +1
1

Please try the below code, it is working

 var array = [[2, 45], [3, 56], [5, 67], [8, 98], [6, 89], [9, 89], [5, 67]];
array.map((x, index) => {
    if (x.includes(56)) {
        console.log(index);
    }
})

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.