2012-04-21 26 views
8

Tôi có một mảng với mảng lồng nhau trông như thế này:Javascript indexOf cho một mảng của mảng không tìm thấy mảng

var tw = [[3, 0], [11, 0], [3, 14], [11, 14]]; 

Khi tôi cố gắng và tìm thấy nếu mảng tw chứa một trôi qua trong mảng, tôi luôn nhận được kết quả là -1.

Ví dụ:

var test = $.inArray([3, 0], tw); 
var test2 = tw.indexOf([3, 0]); 

cả trở lại -1, mặc dù các đối tượng đầu tiên trong mảng là [3,0] Làm thế nào để tìm hiểu xem một mảng cụ thể của mảng được chứa trong mảng của tôi?

Ồ, và tôi chỉ thử nghiệm nó trên IE9 cho đến nay.

+2

[indexOf so sánh tìm kiếmĐối với các phần tử của mảng bằng cách sử dụng phương trình tương đương nghiêm ngặt - được sử dụng bởi toán tử === hoặc ba bằng] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf) - Tôi không thấy một mảng là giá trị đích trong [inarray] (http://api.jquery.com/jQuery.inArray/) hoặc là – mplungjan

+0

Tôi đã đề xuất-chỉnh sửa thẻ jQuery vì ' $ .inArray' cùng với các thay đổi nhỏ khác, tuy nhiên tôi không hoàn toàn chắc chắn nếu đó là jQuery hoặc nếu bạn muốn giải pháp jQuery (undo/cải thiện/từ chối nếu đó là trường hợp) – ajax333221

Trả lời

10

Đó là vì bạn đang tìm kiếm một đối tượng khác. indexOf() sử dụng so sánh bình đẳng nghiêm ngặt (như nhà điều hành ===) và [3, 0] === [3, 0] trả về sai.

Bạn sẽ cần tìm kiếm theo cách thủ công. Dưới đây là một ví dụ sử dụng một indexOf() hàm tổng quát hơn là sử dụng một chức năng tùy chỉnh Comparer (với một sự cải tiến được đề xuất bởi @ ajax333221 trong các ý kiến):

// Shallow array comparer 
function arraysIdentical(arr1, arr2) { 
    var i = arr1.length; 
    if (i !== arr2.length) { 
     return false; 
    } 
    while (i--) { 
     if (arr1[i] !== arr2[i]) { 
      return false; 
     } 
    } 
    return true; 
} 

function indexOf(arr, val, comparer) { 
    for (var i = 0, len = arr.length; i < len; ++i) { 
     if (i in arr && comparer(arr[i], val)) { 
      return i; 
     } 
    } 
    return -1; 
} 

var tw = [[3, 0], [11, 0], [3, 14], [11, 14]]; 
alert(indexOf(tw, [3, 0], arraysIdentical)); // Alerts 0 
+0

, xem [ví dụ cập nhật ] (http://jsfiddle.net/Da5GS/2/) (jsFiddle khác đã sai) vì sao bạn nên sử dụng 'if (i trong arr && comparer (arr [i], val))' – ajax333221

+0

@ ajax333221: Ahhhh, tôi nghĩ bạn đã gợi ý esting sử dụng 'for ... in'. Lấy làm tiếc. Vâng, đó chắc chắn là một sự cải tiến, mặc dù nó không có sự khác biệt đối với trường hợp của câu hỏi cụ thể này và tôi cho rằng việc thiết lập rõ ràng một thuộc tính mảng thành 'undefined' là yêu cầu sự cố. Tôi sẽ cập nhật câu trả lời của mình. –

+0

cảm ơn bạn đã làm rõ. Điều này hoạt động hoàn hảo! –

2

Mảng là đối tượng. [3, 0] không bằng [3, 0] vì chúng là các đối tượng khác nhau. Đó là lý do tại sao inArray của bạn thất bại.

0

Điều này là do $.inArrayindexOf cả hai đều sử dụng so sánh nông bằng cách sử dụng ===.

Vì mảng bạn đang truyền là indexOf không giống chính xác trong bộ nhớ giống như bộ nhớ trong mảng 2D của bạn, === trả về sai. Bạn sẽ cần phải làm một so sánh sâu để tìm các mảng đúng - từ một cái nhìn nhanh chóng tại các tài liệu jQuery, điều này là không có sẵn ở đó.

2

Vì bạn đang so sánh hai trường hợp khác nhau của mảng. So sánh các đối tượng trả về true chỉ khi chúng giống nhau, không quan trọng nếu chúng chứa cùng một dữ liệu.

Trong trường hợp của bạn, bạn có thể sử dụng phương pháp này:

var tw = [[3, 0], [11, 0], [3, 14], [11, 14]]; 

if (~tw.join(";").split(";").indexOf(String([3, 0]))) { 
    // ... 
} 

Hoặc một cái gì đó hơn ortodox thích:

if (tw.filter(function(v) { return String(v) === String([3, 10]) })[0]) { 
    // ... 
} 

đâu tình trạng này có thể được điều chỉnh tùy thuộc vào nội dung của mảng.

2

Đối với vô hạn tìm kiếm lồng nhau:

function indexOfArr(arr1, fnd1) { 
    var i, len1; 

    //compare every element on the array 
    for (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], fnd1)) { 
      return i; 
     } 
    } 

    //no match found, return false 
    return -1; 
} 

function elementComparer(fnd1, fnd2) { 
    var i, len1, len2, type1, type2, iin1, iin2; 

    //store the types of fnd1 and fnd2 
    type1 = typeof fnd1; 
    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") { 
      len1 = fnd1.length; 

      //unwanted results with '(typeof null==="object")===true' so we exclude them 
      if (type2 == "object" && fnd2 + "" != "null") { 
       len2 = fnd2.length; 

       //if they aren't the same length, return false 
       if (len1 !== len2) { 
        return false; 
       } 

       //compare every element on the array 
       for (i = 0; i < len1; i++) { 

        iin1 = i in fnd1; 
        iin2 = i in fnd2; 

        //if either index is missing... 
        if (!(iin1 && iin2)) { 

         //they both are missing, leave to prevent false-positives with 'undefined' 
         if (iin1 == iin2) { 
          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 { 
       //NOT the same, return false 
       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; 
} 

Ghi chú:

  • hỗ trợ mảng lồng nhau vô hạn
  • xử lý mảng thưa thớt một cách chính xác
  • sử dụng typeof kiểm tra

jsFiddle demo

+0

Tôi dành hàng giờ để hiểu rằng 'NaN! == NaN' là' true' và 'typeof null' là' "object" ' – ajax333221

0

Tại sao không giữ đơn giản?

function indexOfCustom (parentArray, searchElement) { 
    for (var i = 0; i < parentArray.length; i++) { 
     if (parentArray[i][0] == searchElement[0] && parentArray[i][1] == searchElement[1]) { 
      return i; 
     } 
    } 
    return -1; 
} 
Các vấn đề liên quan