2

I have a list of lists which comes from the server in ajax response has following structure:

var mapping = [     //response.mapping
    ["userOne", 1],
    ["userTwo", 2],
    ["userthree", 3],
    ["userfour", 4],

    ["personOne", 1],
    ["personTwo", 2],
    ["personOne", 3],
];

As the list will be constant forever, which will have only 7 elements at anytime. I want index of any of its element to update some DOM elements.

// Gives me any of list element which is random elm of the list `mapping`.
var captured_list_elm =  process_mapping_list();     
var status = mapping.indexOf(captured_list_elm);// getting always -1

Here I'm getting always -1 for status.

  • What could be the reason?
  • Why indexOf can not calculate its index?
  • What's the way to find it, get index through looping over list only?

Created a jsFiddle

NOTE - Actually it should be a json but someone out of our team had written it as a list of lists. I can not update it as of now because the code is in production.

Laxmikant
  • 2,046
  • 3
  • 30
  • 44

4 Answers4

5

Array.indexOf() uses strict equality (===) to find an element. The elements of mapping are arrays and two distinct arrays that happen to have the same elements are not ===. I suspect that process_mapping_list() is returning an array that looks like one of the elements of mapping but is not the element itself (just like your fiddle does).

You might need to write your own look-up function that uses a custom equality test. For such a test, take a look at this thread. Depending on the environment(s) you are targeting, you may be able to use findIndex() instead of indexOf(). That function allows you to supply your own testing function.

Community
  • 1
  • 1
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
0

Here's a way to get around the === issue with indexOf...

Option 1:

.

 var mapping = [     //response.mapping
    ["userOne", 1],
    ["userTwo", 2],
    ["userthree", 3],
    ["userfour", 4],

    ["personOne", 1],
    ["personTwo", 2],
    ["personOne", 3],
 ];

 var jsonMapping = [];
 for (var i = 0; i < mapping.length; i++) {
    jsonMapping.push(JSON.stringify(mapping[i]));
 }
 var captured_list_elm = ["personOne", 1];
 var status = jsonMapping.indexOf(JSON.stringify(captured_list_elm));
 alert("status= "+status);

Option 2

.

var mapping = [     //response.mapping
    ["userOne", 1],
    ["userTwo", 2],
    ["userthree", 3],
    ["userfour", 4],

    ["personOne", 1],
    ["personTwo", 2],
    ["personOne", 3],
];
var findIndex = function (hayStack, needle) {
    for (var i = 0; i < hayStack.length; i++) {
        if(hayStack[i][0] === needle[0] && hayStack[i][1] === needle[1]) {
            return i;
        }
    }
    return -1;
};
var captured_list_elm = ["personOne", 1];
var status = findIndex(mapping, captured_list_elm);
alert("status= "+status);
Seth McClaine
  • 9,142
  • 6
  • 38
  • 64
0

To confirm the answer @ted-hopp gave I forked your JSFiddle and slightly modified it. Basically what I did was to move the variable captured_list_elm to the top and add it as a value to the array. As you can see now Array.indexOf returns 4 which is the correct (zero-based) index:

var captured_list_elm = ["personOne", 1];

var mapping = [     //response.mapping
    ["userOne", 1],
    ["userTwo", 2],
    ["userthree", 3],
    ["userfour", 4],
    captured_list_elm,
    ["personTwo", 2],
    ["personOne", 3],
];

var status = mapping.indexOf(captured_list_elm);
alert("status= "+status);

What you probably have to do is to add a for loop that iterates over your array and compares the values.

0

The problem is that you're comparing two arrays using indexOf. If you run your jsFiddle with this code, it'll return the right index because it's comparing the array itself, not the elements within it.

var status = mapping.indexOf(mapping[6]);
Roberto Soares
  • 244
  • 1
  • 11