Tôi có nhiều mảng sẽ chứa
story & message
hay chỉ
story
Làm cách nào để kiểm tra xem một mảng có chứa cả câu chuyện và tin nhắn hay không? array_key_exists()
chỉ tìm kiếm khóa duy nhất đó trong mảng.
Có cách nào để làm việc này không?
Tôi có nhiều mảng sẽ chứa
story & message
hay chỉ
story
Làm cách nào để kiểm tra xem một mảng có chứa cả câu chuyện và tin nhắn hay không? array_key_exists()
chỉ tìm kiếm khóa duy nhất đó trong mảng.
Có cách nào để làm việc này không?
array_intersect_key()
so sánh một mảng khóa bạn muốn xác minh với mảng bạn đang kiểm tra. Nếu độ dài của đầu ra giống với dãy khóa cần kiểm tra, chúng đều có mặt.
["story & message" => "value"]
hay giống hơn["story & message"]
Câu trả lời:
Nếu bạn chỉ có 2 chìa khóa để kiểm tra (như trong câu hỏi ban đầu), có lẽ bạn chỉ cần gọi array_key_exists()
hai lần để kiểm tra xem chìa khóa có tồn tại hay không.
if (array_key_exists("story", $arr) && array_key_exists("message", $arr)) {
// Both keys exist.
}
Tuy nhiên, điều này rõ ràng không mở rộng quy mô tốt cho nhiều phím. Trong tình huống đó, một chức năng tùy chỉnh sẽ hữu ích.
function array_keys_exists(array $keys, array $arr) {
return !array_diff_key(array_flip($keys), $arr);
}
!array_diff($keys, array_keys($array));
vì có ít tải trọng nhận thức hơn liên quan đến việc tìm ra những thứ array_flip
đó.
Đây là một giải pháp có thể mở rộng, ngay cả khi bạn muốn kiểm tra một số lượng lớn khóa:
<?php
// The values in this arrays contains the names of the indexes (keys)
// that should exist in the data array
$required = array('key1', 'key2', 'key3');
$data = array(
'key1' => 10,
'key2' => 20,
'key3' => 30,
'key4' => 40,
);
if (count(array_intersect_key(array_flip($required), $data)) === count($required)) {
// All required keys exist!
}
Đáng ngạc nhiên là array_keys_exist
không tồn tại ?! Trong thời gian tạm thời, để lại một số không gian để tìm ra một biểu thức dòng duy nhất cho nhiệm vụ chung này. Tôi đang nghĩ đến một kịch bản shell hoặc một chương trình nhỏ khác.
Lưu ý: mỗi giải pháp sau đây sử dụng […]
cú pháp khai báo mảng ngắn gọn có sẵn trong php 5.4+
if (0 === count(array_diff(['story', 'message', '…'], array_keys($source)))) {
// all keys found
} else {
// not all
}
(đầu mũ cho Kim Stacks )
Cách tiếp cận này là ngắn gọn nhất mà tôi tìm thấy. array_diff()
trả về một mảng các mục có trong đối số 1 không có trong đối số 2. Do đó, một mảng trống cho biết tất cả các khóa đã được tìm thấy. Trong php 5.5, bạn có thể đơn giản hóa 0 === count(…)
thành đơn giản empty(…)
.
if (0 === count(array_reduce(array_keys($source),
function($in, $key){ unset($in[array_search($key, $in)]); return $in; },
['story', 'message', '…'])))
{
// all keys found
} else {
// not all
}
Khó đọc hơn, dễ thay đổi. array_reduce()
sử dụng một lệnh gọi lại để lặp qua một mảng để đi đến một giá trị. Bằng cách cung cấp các khóa, chúng tôi quan tâm đến $initial
giá trị của $in
và sau đó xóa các khóa được tìm thấy trong nguồn, chúng tôi có thể mong đợi kết thúc bằng 0 phần tử nếu tất cả các khóa được tìm thấy.
Cấu trúc dễ dàng sửa đổi vì các phím mà chúng tôi quan tâm nằm vừa vặn ở điểm mấu chốt.
if (2 === count(array_filter(array_keys($source), function($key) {
return in_array($key, ['story', 'message']); }
)))
{
// all keys found
} else {
// not all
}
Viết đơn giản hơn so với array_reduce
giải pháp nhưng hơi khó chỉnh sửa. array_filter
cũng là một lệnh gọi lại lặp đi lặp lại cho phép bạn tạo một mảng đã lọc bằng cách trả về true (sao chép mục vào mảng mới) hoặc false (không sao chép) trong lệnh gọi lại. Điểm mấu chốt là bạn phải thay đổi 2
số lượng mặt hàng mà bạn mong đợi.
Điều này có thể được làm lâu bền hơn nhưng rất nguy hiểm về khả năng đọc:
$find = ['story', 'message'];
if (count($find) === count(array_filter(array_keys($source), function($key) use ($find) { return in_array($key, $find); })))
{
// all keys found
} else {
// not all
}
Đối với tôi, dường như phương pháp đơn giản nhất cho đến nay sẽ là:
$required = array('a','b','c','d');
$values = array(
'a' => '1',
'b' => '2'
);
$missing = array_diff_key(array_flip($required), $values);
Bản in:
Array(
[c] => 2
[d] => 3
)
Điều này cũng cho phép kiểm tra chính xác khóa nào bị thiếu. Điều này có thể hữu ích cho việc xử lý lỗi.
Các giải pháp trên là khéo léo, nhưng rất chậm. Một vòng lặp foreach đơn giản với Isset nhanh hơn gấp đôi so với array_intersect_key
giải pháp.
function array_keys_exist($keys, $array){
foreach($keys as $key){
if(!array_key_exists($key, $array))return false;
}
return true;
}
(344ms so với 768ms cho 1000000 lần lặp)
false
( false
ghi đè true
trong trường hợp này). Vì vậy, những gì làm việc cho nhu cầu của tôi là foreach ($keys as $key) { if (array_key_exists($key, $array)) { return true; }} return false;
nhu cầu của tôi là nếu any
chủ chốt trong một mảng tồn tại trong mảng khác ...
Nếu bạn có một cái gì đó như thế này:
$stuff = array();
$stuff[0] = array('story' => 'A story', 'message' => 'in a bottle');
$stuff[1] = array('story' => 'Foo');
Bạn có thể chỉ cần count()
:
foreach ($stuff as $value) {
if (count($value) == 2) {
// story and message
} else {
// only story
}
}
Điều này chỉ hoạt động nếu bạn biết chắc chắn rằng bạn CHỈ có các khóa mảng này và không có gì khác.
Sử dụng array_key_exists () chỉ hỗ trợ kiểm tra một khóa tại một thời điểm, vì vậy bạn sẽ cần kiểm tra cả hai khóa riêng biệt:
foreach ($stuff as $value) {
if (array_key_exists('story', $value) && array_key_exists('message', $value) {
// story and message
} else {
// either one or both keys missing
}
}
array_key_exists()
trả về true nếu khóa có trong mảng, nhưng nó là một hàm thực và có rất nhiều thứ để nhập. Cấu trúc ngôn ngữ isset()
gần như sẽ hoạt động tương tự, ngoại trừ nếu giá trị được kiểm tra là NULL:
foreach ($stuff as $value) {
if (isset($value['story']) && isset($value['message']) {
// story and message
} else {
// either one or both keys missing
}
}
Ngoài ra, Isset cho phép kiểm tra nhiều biến cùng một lúc:
foreach ($stuff as $value) {
if (isset($value['story'], $value['message']) {
// story and message
} else {
// either one or both keys missing
}
}
Bây giờ, để tối ưu hóa thử nghiệm cho những thứ đã được thiết lập, bạn tốt hơn nên sử dụng "nếu" này:
foreach ($stuff as $value) {
if (isset($value['story']) {
if (isset($value['message']) {
// story and message
} else {
// only story
}
} else {
// No story - but message not checked
}
}
Cái này thì sao:
isset($arr['key1'], $arr['key2'])
chỉ trả về true nếu cả hai đều không rỗng
nếu là null, khóa không có trong mảng
$arr['key1']
hoặc $arr['key2']
là null
, mã sẽ tồn tại, khóa vẫn tồn tại.
foreach
vòng lặp?
isset
hàm hoạt động theo ý tôi, nhưng bây giờ tôi nhận ra rằng bạn đã đúng, các khóa vẫn còn trong một mảng và do đó câu trả lời của tôi là không đúng, cảm ơn bạn đã phản hồi. Có, tôi có thể sử dụng nó foreach
.
Tôi sử dụng một cái gì đó như thế này khá thường xuyên
$wantedKeys = ['story', 'message'];
$hasWantedKeys = count(array_intersect(array_keys($source), $wantedKeys)) > 0
hoặc để tìm các giá trị cho các khóa mong muốn
$wantedValues = array_intersect_key($source, array_fill_keys($wantedKeys, 1))
Đây là hàm tôi đã viết cho chính mình để sử dụng trong một lớp.
<?php
/**
* Check the keys of an array against a list of values. Returns true if all values in the list
is not in the array as a key. Returns false otherwise.
*
* @param $array Associative array with keys and values
* @param $mustHaveKeys Array whose values contain the keys that MUST exist in $array
* @param &$missingKeys Array. Pass by reference. An array of the missing keys in $array as string values.
* @return Boolean. Return true only if all the values in $mustHaveKeys appear in $array as keys.
*/
function checkIfKeysExist($array, $mustHaveKeys, &$missingKeys = array()) {
// extract the keys of $array as an array
$keys = array_keys($array);
// ensure the keys we look for are unique
$mustHaveKeys = array_unique($mustHaveKeys);
// $missingKeys = $mustHaveKeys - $keys
// we expect $missingKeys to be empty if all goes well
$missingKeys = array_diff($mustHaveKeys, $keys);
return empty($missingKeys);
}
$arrayHasStoryAsKey = array('story' => 'some value', 'some other key' => 'some other value');
$arrayHasMessageAsKey = array('message' => 'some value', 'some other key' => 'some other value');
$arrayHasStoryMessageAsKey = array('story' => 'some value', 'message' => 'some value','some other key' => 'some other value');
$arrayHasNone = array('xxx' => 'some value', 'some other key' => 'some other value');
$keys = array('story', 'message');
if (checkIfKeysExist($arrayHasStoryAsKey, $keys)) { // return false
echo "arrayHasStoryAsKey has all the keys<br />";
} else {
echo "arrayHasStoryAsKey does NOT have all the keys<br />";
}
if (checkIfKeysExist($arrayHasMessageAsKey, $keys)) { // return false
echo "arrayHasMessageAsKey has all the keys<br />";
} else {
echo "arrayHasMessageAsKey does NOT have all the keys<br />";
}
if (checkIfKeysExist($arrayHasStoryMessageAsKey, $keys)) { // return false
echo "arrayHasStoryMessageAsKey has all the keys<br />";
} else {
echo "arrayHasStoryMessageAsKey does NOT have all the keys<br />";
}
if (checkIfKeysExist($arrayHasNone, $keys)) { // return false
echo "arrayHasNone has all the keys<br />";
} else {
echo "arrayHasNone does NOT have all the keys<br />";
}
Tôi giả sử bạn cần kiểm tra nhiều khóa TẤT CẢ TỒN TẠI trong một mảng. Nếu bạn đang tìm kiếm sự phù hợp của ít nhất một khóa, hãy cho tôi biết để tôi có thể cung cấp một chức năng khác.
Codepad tại đây http://codepad.viper-7.com/AKVPCH
if (0 === count(array_diff(['key1','key2','key3'], array_keys($lookIn)))) { // all keys exist } else { // nope }
Điều này đã cũ và có thể sẽ bị chôn vùi, nhưng đây là nỗ lực của tôi.
Tôi đã gặp sự cố tương tự với @Ryan. Trong một số trường hợp, tôi chỉ cần kiểm tra xem có ít nhất 1 khóa nằm trong một mảng hay không và trong một số trường hợp, tất cả cần phải có mặt.
Vì vậy, tôi đã viết hàm này:
/**
* A key check of an array of keys
* @param array $keys_to_check An array of keys to check
* @param array $array_to_check The array to check against
* @param bool $strict Checks that all $keys_to_check are in $array_to_check | Default: false
* @return bool
*/
function array_keys_exist(array $keys_to_check, array $array_to_check, $strict = false) {
// Results to pass back //
$results = false;
// If all keys are expected //
if ($strict) {
// Strict check //
// Keys to check count //
$ktc = count($keys_to_check);
// Array to check count //
$atc = count(array_intersect($keys_to_check, array_keys($array_to_check)));
// Compare all //
if ($ktc === $atc) {
$results = true;
}
} else {
// Loose check - to see if some keys exist //
// Loop through all keys to check //
foreach ($keys_to_check as $ktc) {
// Check if key exists in array to check //
if (array_key_exists($ktc, $array_to_check)) {
$results = true;
// We found at least one, break loop //
break;
}
}
}
return $results;
}
Điều này dễ dàng hơn rất nhiều so với việc phải viết nhiều ||
và &&
khối.
<?php
function check_keys_exists($keys_str = "", $arr = array()){
$return = false;
if($keys_str != "" and !empty($arr)){
$keys = explode(',', $keys_str);
if(!empty($keys)){
foreach($keys as $key){
$return = array_key_exists($key, $arr);
if($return == false){
break;
}
}
}
}
return $return;
}
// chạy demo
$key = 'a,b,c';
$array = array('a'=>'aaaa','b'=>'ccc','c'=>'eeeee');
var_dump( check_keys_exists($key, $array));
Tôi không chắc, nếu đó là ý tưởng tồi nhưng tôi sử dụng vòng lặp foreach rất đơn giản để kiểm tra nhiều khóa mảng.
// get post attachment source url
$image = wp_get_attachment_image_src(get_post_thumbnail_id($post_id), 'single-post-thumbnail');
// read exif data
$tech_info = exif_read_data($image[0]);
// set require keys
$keys = array('Make', 'Model');
// run loop to add post metas foreach key
foreach ($keys as $key => $value)
{
if (array_key_exists($value, $tech_info))
{
// add/update post meta
update_post_meta($post_id, MPC_PREFIX . $value, $tech_info[$value]);
}
}
$myArray = array('key1' => '', 'key2' => '');
$keys = array('key1', 'key2', 'key3');
$keyExists = count(array_intersect($keys, array_keys($myArray)));
Sẽ trả về true, vì có các khóa từ mảng $ key trong $ myArray
Một cái gì đó như cái này có thể được sử dụng
//Say given this array
$array_in_use2 = ['hay' => 'come', 'message' => 'no', 'story' => 'yes'];
//This gives either true or false if story and message is there
count(array_intersect(['story', 'message'], array_keys($array_in_use2))) === 2;
Lưu ý đánh dấu chọn 2, nếu các giá trị bạn muốn tìm kiếm khác nhau, bạn có thể thay đổi.
Giải pháp này có thể không hiệu quả, nhưng nó hoạt động!
Cập nhật
Trong một hàm chất béo :
/**
* Like php array_key_exists, this instead search if (one or more) keys exists in the array
* @param array $needles - keys to look for in the array
* @param array $haystack - the <b>Associative</b> array to search
* @param bool $all - [Optional] if false then checks if some keys are found
* @return bool true if the needles are found else false. <br>
* Note: if hastack is multidimentional only the first layer is checked<br>,
* the needles should <b>not be<b> an associative array else it returns false<br>
* The array to search must be associative array too else false may be returned
*/
function array_keys_exists($needles, $haystack, $all = true)
{
$size = count($needles);
if($all) return count(array_intersect($needles, array_keys($haystack))) === $size;
return !empty(array_intersect($needles, array_keys($haystack)));
}
Vì vậy, ví dụ với điều này:
$array_in_use2 = ['hay' => 'come', 'message' => 'no', 'story' => 'yes'];
//One of them exists --> true
$one_or_more_exists = array_keys_exists(['story', 'message'], $array_in_use2, false);
//all of them exists --> true
$all_exists = array_keys_exists(['story', 'message'], $array_in_use2);
Hi vọng điêu nay co ich :)
Tôi thường sử dụng một chức năng để xác thực bài đăng của mình và nó cũng là câu trả lời cho câu hỏi này, vì vậy hãy để tôi đăng nó.
để gọi hàm của tôi, tôi sẽ sử dụng 2 mảng như thế này
validatePost(['username', 'password', 'any other field'], $_POST))
thì chức năng của tôi sẽ như thế này
function validatePost($requiredFields, $post)
{
$validation = [];
foreach($requiredFields as $required => $key)
{
if(!array_key_exists($key, $post))
{
$validation['required'][] = $key;
}
}
return $validation;
}
cái này sẽ xuất ra cái này
"bắt buộc": ["tên người dùng", "mật khẩu", "bất kỳ trường nào khác"]
vì vậy những gì chức năng này làm là xác thực và trả về tất cả các trường bị thiếu của yêu cầu đăng.