I recently wrote a snippet to make a custom array.indexOf but with nested array support in addition to allow using a nested array as needle.
For example, it correctly returns the index 3
in this case:
var arr1=[0,1,2,[3,[4,true,[],[,"x",false,,,undefined,[]]],["5"]]];
console.log(indexOfArr(arr1,[3,[4,true,[],[,"x",false,,,undefined,[]]],["5"]]));//3
Here is the un-commented snippet (if you want to read the commented version, skip this one):
function indexOfArr(arr1, fnd) {
for (var i = 0, len1 = arr1.length; i < len1; i++) {
if (!(i in arr1)) {
continue;
}
if (elementComparer(arr1[i], fnd)) {
return i;
}
}
return -1;
}
function elementComparer(fnd1, fnd2) {
var type1 = typeof fnd1;
var type2 = typeof fnd2;
if (!((type1 == "number" && type2 == "number") && (fnd1 + "" == "NaN" && fnd2 + "" == "NaN"))) {
if (type1 == "object" && fnd1 + "" != "null") {
var len1 = fnd1.length;
if (type2 == "object" && fnd2 + "" != "null") {
var len2 = fnd2.length;
if (len1 !== len2) {
return false;
}
for (var i = 0; i < len1; i++) {
if (!(i in fnd1 && i in fnd2)) {
if (i in fnd1 == i in fnd2) {
continue;
}
return false;
}
if (!elementComparer(fnd1[i], fnd2[i])) {
return false;
}
}
}
} else {
if (fnd1 !== fnd2) {
return false;
}
}
}
return true;
}
Here the commented snippet:
function indexOfArr(arr1,fnd){
//compare every element on the array
for(var i=0,len1=arr1.length;i<len1;i++){
//index missing, leave to prevent false-positives with 'undefined'
if(!(i in arr1)){
continue;
}
//if they are exactly equal, return the index
if(elementComparer(arr1[i],fnd)){
return i;
}
}
//no match found, return false
return -1;
}
function elementComparer(fnd1,fnd2){
//store the types of fnd1 and fnd2
var type1=typeof fnd1;
var type2=typeof fnd2;
//unwanted results with '(NaN!==NaN)===true' so we exclude them
if(!((type1=="number"&&type2=="number")&&(fnd1+""=="NaN"&&fnd2+""=="NaN"))){
//unwanted results with '(typeof null==="object")===true' so we exclude them
if(type1=="object"&&fnd1+""!="null"){
var len1=fnd1.length;
//unwanted results with '(typeof null==="object")===true' so we exclude them
if(type2=="object"&&fnd2+""!="null"){
var len2=fnd2.length;
//if they aren't the same length, return false
if(len1!==len2){
return false;
}
//compare every element on the array
for(var i=0;i<len1;i++){
//if either index is missing...
if(!(i in fnd1&&i in fnd2)){
//they both are missing, leave to prevent false-positives with 'undefined'
if(i in fnd1==i in fnd2){
continue;
}
//NOT the same, return false
return false;
}
//if they are NOT the same, return false
if(!elementComparer(fnd1[i],fnd2[i])){
return false;
}
}
}
}else{
//if they are NOT the same, return false
if(fnd1!==fnd2){
return false;
}
}
}
//if it successfully avoided all 'return false', then they are equal
return true;
}
Things that I want to know:
- Do you find it readable?
- Are there any obvious improvements (other than minifying)?
- What practice is not recommended?