JavaScript tương đương với in_array () của PHP


223

Có cách nào trong JavaScript để so sánh các giá trị từ một mảng và xem nó có ở mảng khác không?

Tương tự như in_arraychức năng của PHP ?

Câu trả lời:


258

Không, nó không có. Vì lý do này, hầu hết các thư viện phổ biến đi kèm với một trong các gói tiện ích của họ. Kiểm tra các ví dụ inArray và Prototype của Array.indexOf của jQuery .

Việc triển khai jQuery của nó đơn giản như bạn mong đợi:

function inArray(needle, haystack) {
    var length = haystack.length;
    for(var i = 0; i < length; i++) {
        if(haystack[i] == needle) return true;
    }
    return false;
}

Nếu bạn đang xử lý một lượng lớn các phần tử mảng, ở trên sẽ thực hiện thủ thuật độc đáo.

EDIT : Rất tiếc. Tôi thậm chí không nhận thấy bạn muốn xem nếu một mảng nằm trong một mảng khác. Theo tài liệu PHP, đây là hành vi dự kiến ​​của PHP in_array:

$a = array(array('p', 'h'), array('p', 'r'), 'o');

if (in_array(array('p', 'h'), $a)) {
    echo "'ph' was found\n";
}

if (in_array(array('f', 'i'), $a)) {
    echo "'fi' was found\n";
}

if (in_array('o', $a)) {
    echo "'o' was found\n";
}

// Output:
//  'ph' was found
//  'o' was found

Mã được đăng bởi Chris và Alex không tuân theo hành vi này. Alex's là phiên bản chính thức của indexOf của Prototype và Chris giống với PHP hơn array_intersect. Đây là những gì bạn muốn:

function arrayCompare(a1, a2) {
    if (a1.length != a2.length) return false;
    var length = a2.length;
    for (var i = 0; i < length; i++) {
        if (a1[i] !== a2[i]) return false;
    }
    return true;
}

function inArray(needle, haystack) {
    var length = haystack.length;
    for(var i = 0; i < length; i++) {
        if(typeof haystack[i] == 'object') {
            if(arrayCompare(haystack[i], needle)) return true;
        } else {
            if(haystack[i] == needle) return true;
        }
    }
    return false;
}

Và đây là bài kiểm tra của tôi về những điều trên:

var a = [['p','h'],['p','r'],'o'];
if(inArray(['p','h'], a)) {
    alert('ph was found');
}
if(inArray(['f','i'], a)) {
    alert('fi was found');
}
if(inArray('o', a)) {
    alert('o was found');
}  
// Results:
//   alerts 'ph' was found
//   alerts 'o' was found

Lưu ý rằng tôi cố tình không mở rộng nguyên mẫu Array vì nói chung là một ý tưởng tồi để làm như vậy.


1
jQuery.inArray()không không trở boolean. Nó trả về chỉ mục của phần tử được tìm thấy hoặc -1 nếu không tìm thấy
Brad Kent

Do xếp hạng cao - bạn nên đánh dấu câu trả lời của mình là lỗi thời
Gerfried

1
đây là tài liệu của indexOf w3schools.com/jsref/jsref_indexof_array.asp
yussan

74

Hiện tại có Array.prototype.includes:

Phương thức include () xác định xem một mảng có bao gồm một phần tử nhất định hay không, trả về true hoặc false khi thích hợp.

var a = [1, 2, 3];
a.includes(2); // true 
a.includes(4); // false

Cú pháp

arr.includes(searchElement)
arr.includes(searchElement, fromIndex)

66

Array.indexOfđã được giới thiệu trong JavaScript 1.6, nhưng nó không được hỗ trợ trong các trình duyệt cũ hơn. Rất may, các lỗi trong Mozilla đã thực hiện tất cả công việc khó khăn cho bạn và cung cấp cho bạn điều này để tương thích:

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

Thậm chí có một số đoạn sử dụng tiện dụng cho niềm vui kịch bản của bạn.


Đây là cách thực hiện tốt hơn / an toàn hơn / tốt hơn cho các liên kết / mã được đăng ở đây; thông số kỹ thuật không gọi để kiểm tra các mảng bên trong đống cỏ khô, và đó là những gì OP muốn.
Paolo Bergantino

3
Ngẫu nhiên, mục đích của là this.length >>> 0gì? Đó có phải là một chuyển đổi sang một loại số?
harto

3
Array.indexOfhiện được chuẩn hóa bởi ECMAScript Fifth Edition, do đó, nên được coi là cách làm 'bản địa' thích hợp. Mặc dù vậy, bạn vẫn sẽ cần phải đánh hơi và cung cấp bản sao lưu này cho trình duyệt cũ hơn trong một thời gian dài. @harto: có, nó chuyển đổi this.lengththành Số có thể được biểu diễn dưới dạng số nguyên không dấu 32 bit. Một người bản địa Arraychỉ có thể có một độ dài đã tuân thủ điều này, nhưng thông số kỹ thuật nói rằng bạn có thể gọi Array.prototypecác phương thức trên các đối tượng JS gốc không có Array. Điều này và các công cụ kiểm tra đối số phạm vi khác là để đảm bảo tuân thủ tuyệt đối.
bobince

3
Có một phiên bản polyfill khác nhau có sẵn trực tiếp từ Mozilla - developer.mozilla.org/en/docs/Web/JavaScript/Reference/
Kẻ

@harto Tôi trả lời 8 năm sau bình luận của bạn nhưng có lẽ ai đó có thể có cùng câu hỏi => xem stackoverflow.com/questions/1822350/
trộm

14

Nếu các chỉ mục không theo trình tự hoặc nếu các chỉ mục không liên tiếp, mã trong các giải pháp khác được liệt kê ở đây sẽ bị hỏng. Một giải pháp có thể hoạt động tốt hơn có thể là:

function in_array(needle, haystack) {
    for(var i in haystack) {
        if(haystack[i] == needle) return true;
    }
    return false;
}

Và, như một phần thưởng, đây là tương đương với mảng_search của PHP (để tìm khóa của phần tử trong mảng:

function array_search(needle, haystack) {
    for(var i in haystack) {
        if(haystack[i] == needle) return i;
    }
    return false;
}

Đẹp giảm trong thay thế. Thực sự làm cho việc chuyển từ php sang nút dễ dàng. cảm ơn
Rahim Khoja

9

Có một dự án tên là Locutus , nó thực hiện các hàm PHP trong Javascript và in_array () được bao gồm, bạn có thể sử dụng chính xác như bạn sử dụng trong PHP.

Ví dụ sử dụng:

in_array('van', myArray);

in_array(1, otherArray, true); // Forcing strict type

4
Ngoài ra còn có một hàm inArray trong API của JQuery. Kiểm tra api.jquery.com/jQuery.inArray
ahPo

@ahPo, đẹp quá! Nhưng việc triển khai Locutus có lợi thế là javascript thuần túy không có phụ thuộc. Vì vậy, hãy chọn một thứ tốt nhất cho nhu cầu của bạn
Marcio Mazzucato

1
hoặc bạn chỉ có thể nhập chức năng cần thiết từ Locutus.
Niket Pathak


5
var a = [1,2,3,4,5,6,7,8,9];

var isSixInArray = a.filter(function(item){return item==6}).length ? true : false;

var isSixInArray = a.indexOf(6)>=0;

5

Giải pháp jQuery đã có sẵn, hãy kiểm tra phần trích dẫn tại đây: http://api.jquery.com/jquery.inarray/

$.inArray( 10, [ 8, 9, 10, 11 ] );

3
đừng quên kiểm tra như thế này: if ($. inArray (10, [8, 9, 10, 11])> -1) bởi vì tôi đã làm như thế này: if ($. inArray (10, [8, 9, 10, 11])) và nó luôn trả về đúng
temirbek

PS: Đây là loại nhạy cảm, vì vậy nếu kiểm tra các con số, hãy đảm bảo các kiểu dữ liệu của bạn khớp với! tức là: $ .inArray ('10', [8, 9, 10, 11]); sẽ trở lại -1
Oliver M Grech


3

Nếu bạn chỉ muốn kiểm tra xem một giá trị có nằm trong một mảng hay không, thì mã của Paolo sẽ thực hiện công việc. Nếu bạn muốn kiểm tra giá trị nào là phổ biến cho cả hai mảng, thì bạn sẽ muốn một cái gì đó như thế này (sử dụng hàm inArray của Paolo):

function arrayIntersect(a, b) {
    var intersection = [];

    for(var i = 0; i < a.length; i++) {
        if(inArray(b, a[i]))
            intersection.push(a[i]);
    }

    return intersection;
}

Điều này sẽ trả về một loạt các giá trị nằm trong cả hai ab. (Về mặt toán học, đây là giao điểm của hai mảng.)

EDIT: Xem Mã chỉnh sửa của Paolo để biết giải pháp cho vấn đề của bạn. :)


Mặc dù điều này là tốt, nhưng nó không thực sự là những gì OP yêu cầu; nó không sao chép chức năng của in_array của PHP.
Paolo Bergantino

3

Nếu bạn cần tất cả các tham số có sẵn của PHP , hãy sử dụng:

function in_array(needle, haystack, argStrict) {
    var key = '', strict = !!argStrict;
    if (strict) {
        for (key in haystack) {
            if (haystack[key] === needle) {
                return true;
            }
        }
    }
    else {
        for (key in haystack) {
            if (haystack[key] == needle) {
                return true;
            }
        }
    }
    return false;
}

3

Thêm mã này cho bạn chiếu và sử dụng các phương thức inArray kiểu đối tượng

if (!Array.prototype.inArray) {
    Array.prototype.inArray = function(element) {
        return this.indexOf(element) > -1;
    };
} 
//How it work
var array = ["one", "two", "three"];
//Return true
array.inArray("one");


2
haystack.find(value => value == needle)

trong đó haystack là một mảng và kim là một yếu tố trong mảng. Nếu phần tử không tìm thấy sẽ được trả về không xác định khác phần tử tương tự.


1
function in_array(what, where) {
    var a=false;
    for (var i=0; i<where.length; i++) {
        if(what == where[i]) {
            a=true;
            break;
        }
    }
    return a;
}

1

Tôi tìm thấy một giải pháp jQuery tuyệt vời ở đây trên SO.

var success = $.grep(array_a, function(v,i) {
    return $.inArray(v, array_b) !== -1;
}).length === array_a.length;

Tôi ước ai đó sẽ đăng một ví dụ về cách làm điều này trong gạch dưới.


1
function in_array(needle, haystack){

    return haystack.indexOf(needle) !== -1;
}

Điều này chỉ trả về cho dù đó là phần tử đầu tiên trong mảng; nếu indexOf(needle) > 0nó sẽ trả về false
DiMono

0

Tương đương in_arrayvới underscore_.indexOf

Ví dụ:

_.indexOf([3, 5, 8], 8); // returns 2, the index of 8 _.indexOf([3, 5, 8], 10); // returns -1, not found


0

Nếu bạn sẽ sử dụng nó trong một lớp và nếu bạn thích nó hoạt động (và hoạt động trong tất cả các trình duyệt):

inArray: function(needle, haystack)
{
    var result = false;

    for (var i in haystack) {
        if (haystack[i] === needle) {
            result = true;
            break;
        }
    }

    return result;
}

Hy vọng nó sẽ giúp được ai đó :-)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.