4

I want to get the indices of the similar values of array1 and array2 and store it to the stored_index variable.

array1 = ["50","51","52","53","54","55","56","57","58","59"];

array2 = ["59","55","51"];

The stored index should look like this.

stored_index = [9,5,1]; // index 9,5,1 is equal to their indices in array 1
KennethC
  • 746
  • 2
  • 10
  • 27
  • 1
    And how far you reach in this? – Manwal Aug 22 '15 at 14:02
  • possible duplicate of [Simplest code for array intersection in javascript](http://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript) – Mark Schultheiss Aug 22 '15 at 14:17
  • You have't completely specified the problem. What goes in the output array in the case where the `array2` element is not found in `array1`? For example, `array2 = ["59","101","51"];` Should the output be `[9,1]` as some of the answers will produce? That seems less than useful, because you don't know *which* of the `array2` elements wasn't found. Should the output be `[9,-1,1]`? That would be a useful result. Or `[9,null,1]` or `[9,undefined,1]`? Either of those would be usable too. But you need to decide which. My personal recommendation is to produce `[9,-1,1]`. – Michael Geary Aug 22 '15 at 19:07

5 Answers5

1

Javascript map() can do this:

var array1 = ["50","51","52","53","54","55","56","57","58","59"];
var array2 = ["59","55","51"];
var stored_index = array2.map(function(val){
    return array1.indexOf(val)
}).filter(function(val){
    return (val != -1)
});

console.log(stored_index)

DEMO


Removing filter:

var array1 = ["50","51","52","53","54","55","56","57","58","59"];
var array2 = ["59","55","51"];
var stored_index = array2.map(function(val){
    return (array1.indexOf(val) != -1) ? array1.indexOf(val) : null;
});

console.log(stored_index)//output [9, 5, 1]

Updated DEMO

Manwal
  • 23,450
  • 12
  • 63
  • 93
  • It gives me 2,1,0 instead of 9,5,1 – KennethC Aug 22 '15 at 14:11
  • @KennethC If you do .filter() over that newly generated array, the load will become more. It will iterate again. So try to skip those -1 while reading that newly generated array. – Rajaprabhu Aravindasamy Aug 22 '15 at 14:14
  • Good catch and great advice @RajaprabhuAravindasamy. Thanks checkout updates. – Manwal Aug 22 '15 at 14:19
  • @Rajaprabhu Aravindasamy - ohh. i see, thanks for the additional info. – KennethC Aug 22 '15 at 14:20
  • The two solutions in your answer do not do the same thing. One elides any missing values from the output array; the other stores `null` in the output for missing values. Eliding the values seems unhelpful, because the output array gives no indication of *which* values were missing. Storing `null` is better, but why not just store `-1` for missing values as in Rajaprabhu's solution? Of course until KennethC tells us which he wants, we're all just guessing. :-) – Michael Geary Aug 22 '15 at 19:12
0

Try to use Array.prototype.map() along with Array.prototype.indexOf() to achieve what you want,

var array1 = ["50","51","52","53","54","55","56","57","58","59"];
var array2 = ["59","55","51"];
var stored_index = array2.map(function(val){
  return array1.indexOf(val);
});

DEMO

Rajaprabhu Aravindasamy
  • 66,513
  • 17
  • 101
  • 130
  • 2
    Will not work for other arrays, for example if you swap array1 with array2. – dfsq Aug 22 '15 at 14:06
  • @dfsq Sorry couldn't understand. What am i doing wrong? Please correct me. Thanks – Rajaprabhu Aravindasamy Aug 22 '15 at 14:07
  • It works now, thanks sir. I can't make an upvote right now because this is a new account. – KennethC Aug 22 '15 at 14:07
  • This is not scalable solution, yes, it works for given data, but it might not for other arrays. For example, http://jsfiddle.net/Ldt6v9xt/1/ – dfsq Aug 22 '15 at 14:09
  • @dfsq Yeah, that case needs to be handled. They have to skip those `-1` data while iterating over that newly genrated array. – Rajaprabhu Aravindasamy Aug 22 '15 at 14:12
  • 1
    @dfsq: Since KennethC didn't tell us what result he wants when values are missing, we are all guessing. However, it is clear that omitting the missing values from the output array is not a useful result. You then have no way of knowing *which* values were missing. Storing `-1` in the array as Rajaprabhu's code does seems to be a perfectly acceptable solution. – Michael Geary Aug 22 '15 at 19:14
0

Just loop through array 2 and use IndexOf function

var array1 = ["50","51","52","53","54","55","56","57","58","59"];
var array2 = ["59","55","51"];
var output = [];
for(var item in array2){
  output.push(array1.indexOf(array2[item]));
}
James McDowell
  • 2,668
  • 1
  • 14
  • 27
  • 3
    [There are a bunch of reasons why you shouldn't use `for in` loops for arrays](http://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-such-a-bad-idea). Use a simple `for (var i = 0, l = arr.length; i < l; i++)` loop instead. – Andy Aug 22 '15 at 14:21
  • In the context that it's being used here, it's fine. If He later adds an element to it like this `array2[5] = 12`, this would not loop over 3 and 4, which don't exist. Also, messing with prototypes is generally bad, so this works here. – James McDowell Aug 22 '15 at 15:10
  • 1
    OK, but I won't be the first person you meet on here that would consider it bad JS practice. – Andy Aug 22 '15 at 15:12
  • I agree with Andy, a numeric `for` loop is greatly preferred over the `for-in` loop. Even if extending `Array.prototype` is discouraged, some libraries do it, and there's no reason to make the code fragile in that case. Also, it's perfectly acceptable and not too uncommon to add non-numeric properties to an individual array, e.g. `var a = [10,20]; a.method = function(){};` A `for-in` loop will include those non-numeric properties, which unlikely to be what you want. Sure, it doesn't matter in this particular case, but why not use the more reliable numeric `for` loop? – Michael Geary Aug 22 '15 at 19:00
  • @Andy: BTW, in modern JavaScript engines, there's no advantage to caching the `.length` property. You'll get the same performance with the simpler `for( var i = 0; i < arr.length; ++i )` loop. – Michael Geary Aug 22 '15 at 19:02
0

If by any chance you need both the index list and the intersection you could store the intersection in a3 array then index it.

var array1 = ["50", "51", "52", "53", "54", "55", "56", "57", "58", "59"];
var array2 = ["59", "55", "51"];
var a3 = array1.filter(function (n) {
    return array2.indexOf(n) !== -1
});

alert(a3);
stored_index = [];
var i = 0;
for (; i < a3.length; i++) {
    stored_index.push(array1.indexOf(a3[i]));
}
alert(stored_index);

NOTE: for VERY large arrays performance might not be optimal here.

Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
0

Further to the existing answers, I'd suggest:

var array1 = ["50", "51", "52", "53", "54", "55", "56", "57", "58", "59"],
    array2 = ["59", "55", "51"];

// named function, to which arguments are passed:    
function getIndicesOfCommonArrayValues(one, two) {

    // if the named arguments both match the
    // assessment within the Array.prototype.every()
    // anonymous function we proceed, otherwise we
    // do nothing; if every assessment performed
    // returns true, then the method itself returns
    // a Boolean true:
    if ([one, two].every(function (arr) {
        // 'arr' is the current array-value of the array
        // over which we're iterating:

        // here check that the typeof arr is not 'undefined', AND
        // that the constructor of arr is Array; this ensures that
        // we have two defined array-values, and that the array
        // value we're testing is itself an Array:
        return 'undefined' !== typeof arr && arr.constructor === Array;
    })) {

        // here we find the longest array:
        var longestArray = one.length >= two.length ? one : two,
        // here we find the shortest array:
            shortestArray = one.length < two.length ? one : two;

        // we return the array returned by Array.prototype.map(),
        // which iterates over the shortest array:
        return shortestArray.map(function (value) {
            // 'value' is the current array-value of 
            // the array over which we're iterating.

            // if the longestArray contains the current
            // array-value:
            if (longestArray.indexOf(value) > -1) {

                // we return the index of that array
                // value to the array we're creating
                // Array.prototype.map():
                return longestArray.indexOf(value);
            }
        });
    }
}

console.log(getIndicesOfCommonArrayValues(array1, array2));

var array1 = ["50", "51", "52", "53", "54", "55", "56", "57", "58", "59"],
    array2 = ["59", "55", "51"];

function getIndicesOfCommonArrayValues(one, two) {
    if ([one, two].every(function (arr) {
        return 'undefined' !== typeof arr && arr.constructor === Array;
    })) {
        var longestArray = one.length >= two.length ? one : two,
            shortestArray = one.length < two.length ? one : two;
        
        return shortestArray.map(function (value) {
            if (longestArray.indexOf(value) > -1) {
                return longestArray.indexOf(value);
            }
        });
    }
}

console.log(getIndicesOfCommonArrayValues(array1, array2));

External JS Fiddle demo for experimentation and development.

References:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • That seems a bit complicated. Why does the code compare the array lengths and switch the arrays around depending on the length? Admittedly, the problem specification was a bit vague, but the example given says that the output array should contain indices into `array1`. It happens that `array2` is shorter in the example, but there's no indication that array length should affect the result like this. With the array-switching logic, whoever calls this function would *also* have to compare the length so they would know which array the indices were referring to. – Michael Geary Aug 22 '15 at 19:46