简体   繁体   中英

How a three-dimensional array use 'every' function in javascript

how a three-dimension array use the every function, the result is strange:

var foo = [];
foo[0] = [];
foo[1] = [];
foo[0][0] = [];
foo[0][1] = [];
foo[1][0] = [];
foo[1][1] = [];
foo[0][0][0] = "kanon";
foo[0][0][1] = "JOJO";
foo[0][1][0] = "Dio";
foo[0][1][1] = "Sort";
foo[1][0][0] = "What";
foo[1][0][1] = "Gary";
foo[1][1][0] = "Tofu";
foo[1][1][1] = "bili";
var foo2 = ["JOJO","JOJO","mon","ti","JOJO"];
function isJOJO(x){
    if(x === "JOJO"){
        document.write(x + " is JOJO. <br>");
        return true;
    }else{
        document.write(x + " is not JOJO. <br>");
        return false;
    }
}
document.write(foo.every(isJOJO));
document.write("<br><br>");
document.write(foo2.every(isJOJO));

the result in Chrome are following:

kanon,JOJO,Dioo,Sort is not JOJO. 
false

JOJO is JOJO. 
JOJO is JOJO. 
mon is not JOJO. 
false

The result of the one-dimension array foo2 is correct, but the three-dimension array's result is not...

Is the way that I define three-dimension array foo is wrong?

Why it just ordered until Sort , and even print kanon and Dioo ,which is not === "JOJO"

Or who can recommend me an another offical book or website, i am now using this book Object-Oriented JavaScript Second Edition authoritied by Stoyan Stefanov and Kumar Chetan Sharma

Thanks a lot. ^w^

Javascript doesn't have true multidimensional arrays, all arrays are 1-dimensional. However, the elements of an array can be any type, and what you've done is created an array whose elements are other arrays, and those arrays also have arrays as elements.

But array functions like Array.prototype.every only consider the top-level array they're given, they don't recurse into the contained arrays. So when you try:

foo.every(isJOJO)

it calls

isJOJO(foo[0])

which is equivalent to

isJOJO([["kanon","JOJO"],["Dioo","Sort"]])

This is not equal to "JOJO" , so it returns false , and that causes every() to return false .

Both arrays are actually one dimensional. In fact, all arrays in all programming languages are one dimensional. The extra dimensions are just human interpretation of what the one dimensional array contains.

foo is a normal (one dimensional) array that happens to contain an array that contains an array. Let's rewrite your code to make this obvious:

var foo = [];
foo[0] = [['kanon','JOJO'],['Dioo','Sort']];
foo[1] = [['What','Gary'],['Tofu',bili']];

Now it's more obvious that foo contains only two members. It just so happens that those members are arrays.

So foo.every() will iterate over foo[0] and foo[1] . If you need to iterate over the contents of foo then you need to call .every() on them as well like foo[0].every()

您可能要三维地找到

var firstJOJO=foo.find(arr=>arr.find(inner=>inner.find(isJOJO)));

As the other answers describe, the top level elements of foo are arrays, so if you want to look at the values in them, you can use recursion:

 var foo = []; foo[0] = []; foo[1] = []; foo[0][0] = []; foo[0][1] = []; foo[1][0] = []; foo[1][1] = []; foo[0][0][0] = "kanon"; foo[0][0][1] = "JOJO"; foo[0][1][0] = "Dio"; foo[0][1][1] = "Sort"; foo[1][0][0] = "What"; foo[1][0][1] = "Gary"; foo[1][1][0] = "Tofu"; foo[1][1][1] = "bili"; var foo2 = ["JOJO","JOJO","mon","ti","JOJO"]; function isJOJO(x){ if(Array.isArray(x)){ return x.every(isJOJO); }else if(x === "JOJO"){ console.log(x + " is JOJO."); return true; }else{ console.log(x + " is not JOJO."); return false; } } console.log(foo.every(isJOJO)); console.log(foo2.every(isJOJO)); 

Javascript does not do multi-dimensional arrays per se. It does arrays of arrays to the nth degree. So in your case your foo is an array of arrays and each subarray is an array of arrays.

The values that get passed to your isJOJO function when you call foo.every(isJOJO) are therefore an array of arrays. That is why it is not identical to "JOJO".

You will want to test if the value passed into the function is an array or not and if it is, to run: x.every(isJOJO).

The answer posted by Barmar explains in clear terms why the code doesn't work. Start there.

To recursively find elements in your multi-dimensional array, you can write a deepEvery function:

function deepEvery(array, condition) {
  const results = []

  for (let item of array) {
    if (Array.isArray(item)) {
      // Handle internal arrays with a recursive call:
      for (let subitem of deepEvery(item, condition)) results.push(subitem)

    } else {
      // Handle single items by testing the condition:
      if (condition(item)) results.push(item)
    }
  }

  return results
}

For example:

const array = [
  [
    ["foo", "bar"]
  ],
  [ "foo" ],
  "foo"
]

console.log(deepEvery(array, x => x === 'foo'))
# ['foo', 'foo', 'foo']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM