5

Disclaimer: This question is NOT as same as this one.

I have an example of nested array:

var testArray = [
  true,
  "",
  [
    1,
    {a: 2, b: [3, false]},
    [2, []],
    null
  ],
  4,
  undefined,
  [5, "test"],
  function() {}
];

How to get indexOf of a value in nested array, like:

testArray.multiIndexOf(null); //Expected result will be [2, 3]

I will explain what is happening here.

First, we break down testArray to this:

var testArrayExplain = [0, 1, [0, 1, [0, 1], 3], 3, 4, [0, 1], 6];

As you can see here, this array is as much same as above: first layer of array have length of 7, then take a look at value at location #2, we will see another array being nested to first one. As you can remember from above, that null value have the same exact location as location #3 in array at location #2 of first array

So we will have first layer location then second layer location of null: [2, 3], stored in array sorted from first layer to last layer.

Another example:

var testArrayTwo = [1,[2,3,4],5,[6,[7,8],9,10],11,12];
testArrayTwo.multiIndexOf(6); //return [3, 0]

Optional: If an nested array have two same values, then get location of first value, or an array stored both two location? And if value is not in nested array, return -1 like indexOf?

Am I asking too much? And is this question is important for future developers?

3
  • 1
    so, are you asking, how to accomplish this, or are you just bringing up these questions? Commented Oct 8, 2016 at 7:22
  • Its easy to write a solution. But the point to achieve this should be clear. I would plainly iterate inside the collection and return the index. Commented Oct 8, 2016 at 7:27
  • @Syntac I am asking to to accomplish this Commented Oct 8, 2016 at 18:53

3 Answers 3

8

You could iterate the array and stop if the wanted item is found. If possible have a look for nested arrays and proceed.

Array.prototype.multiIndexOf = function (value) {
    var result;
    this.some(function iter(path) {
        return function (a, i) {
            if (a === value) {
                result = path.concat(i);                        
                return true;
            };
            return Array.isArray(a) && a.some(iter(path.concat(i)));
        }
    }([]));
    return result;
}

var testArray = [true, "", [1, { a: 2, b: [3, false] }, [2, []], null], 4, undefined, [5, "test"], function () { }];

console.log(testArray.multiIndexOf(null));
console.log([1, [2, 3, 4], 5, [6, [7, 8], 9, 10], 11, 12].multiIndexOf(6));
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

4 Comments

Damn Nina, you never cease to amaze me. Have you got any suggested resources to get that good.
@Nina Could you please explain your code in depth . I am a complete beginner in Java script . Thank you
@RajGopalbh4, it is a bit more complicated, but you can start by having a look to Array#some and How do JavaScript closures work?.
@Nina . That's fine . I wrote my own logic in core java . I had spent around 2 days to solve this problem in my own way .This is just another way to solve the problem . Here is my java code . Ignore the first 0 in output . Javacode
2

An alternate to @Nina's answer.

As an additional check, I have added

JSON.stringify(array[key]).indexOf(searchVal) > -1

This will ignore a tree of recursion if value is not available.

var testArray = [1, [2, 3, 4], 5, [6, [7, 8], 9, 10], 11, 12]

function findIndex(array, searchVal, pindex) {
  var result = -1;
  var index = -1;
  for (var key in array) {
    index++;
    if (typeof(array[key]) === "object" &&
      JSON.stringify(array[key]).indexOf(searchVal) > -1 &&
      findIndex(array[key], searchVal, index) !== -1) {
      result = index;
      break;
    } else if (typeof(item) !== "object" && array[key] === searchVal) {
      result = index;
      break;
    }
  }
  return pindex || result;
}
var r1 = findIndex(testArray, 2);
var r2 = findIndex(testArray, 3);
var r3 = findIndex(testArray, 8);
console.log("Result: ", r1, r2, r3)

Comments

0

You can accomplish your goal using the following function. It allows you to use deepIndexOf the same way, as you use indexOf on an array:

[1,[5,[2,"abc"]],3,4].deepIndexOf("abc")    //returns [1,1,1]
[1,[5,[2,"abc"]],3,4].deepIndexOf("none")    //returns -1

It however doesn't work for arrays yet. It's easily expendable however.

Array.prototype.deepIndexOf = function (val) {
  for (var i=0; i<this.length; i++) {
    if(this[i] == val)
      return [i];
    var insideIndex = this[i].deepIndexOf ?
            this[i].deepIndexOf(val) : -1;
    if (insideIndex != -1)
       return [i].concat(insideIndex);
  }
  return -1;
}

document.write([1,[5,[2,"abc"]],3,4].deepIndexOf("abc")
               +"<br>");
document.write([1,[5,[2,"abc"]],3,4].deepIndexOf("none"));

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.