여러 배열 키가 있는지 확인하는 방법


87

다음 중 하나를 포함하는 다양한 배열이 있습니다.

story & message

아니면 그냥

story

배열에 스토리와 메시지가 모두 포함되어 있는지 확인하려면 어떻게해야합니까? array_key_exists()배열에서 해당 단일 키만 찾습니다.

이를 수행하는 방법이 있습니까?


2
두 경우 모두 "이야기"가 있으면 "메시지"만 확인하면되는 것 같습니다.
— Wyzard

5
사용 array_intersect_key()당신은 확인하려는 배열을 확인하려는 키의 배열을 비교합니다. 출력 길이가 확인할 키 배열과 같으면 모두 존재하는 것입니다.
— Michael Berkowski

Wyzard, 메시지는 포함하지만 스토리는 포함하지 않는 다른 배열이 있지만 스토리 나 스토리 및 메시지가 포함 된 배열에만 포함되는 다른 키가 있습니다. 감사합니다
— 라이언

여기서 키와 값을 혼동하고 있습니까? 배열은 같은 포맷 ["story & message" => "value"]이상의처럼입니다["story & message"]
— GordonM

답변:


69

확인해야 할 키가 2 개 뿐인 경우 (원래 질문에서와 같이) 키가 있는지 확인하기 위해 array_key_exists()두 번만 호출하는 것이 쉽습니다 .

if (array_key_exists("story", $arr) && array_key_exists("message", $arr)) {
    // Both keys exist.
}

그러나 이것은 분명히 많은 키로 확장되지 않습니다. 이 상황에서 사용자 정의 함수가 도움이 될 것입니다.

function array_keys_exists(array $keys, array $arr) {
   return !array_diff_key(array_flip($keys), $arr);
}

3
사람들이 어레이에 두 개의 멤버가 있는지 확인하는 데 다른 솔루션이 더 좋다고 생각한다면 명확하게 읽을 수있는 코드 나 성능을 좋아하지 않아야합니다. :)
— alex

필요한 키가 상대적으로 적은 경우 가장 간단한 솔루션 일 것입니다. 20 또는 30과 같은 경우 읽을 수없는 경우.
— apokryfos

1
@apokryfos 동의하지만 OP의 질문에 대답합니다.
— alex

2
@alex 유일한 문제는 안에없는 하나의 요소와 그 안에있는 다른 요소가$keys 포함 된 경우 빈 => ( 3v4l 예 )를 반환 한다는 것입니다 ...$arr!array_diff_keyfalse
— CPHPython

3
나는 이것이 사용하여 가독성을 할 수 있다고 생각 !array_diff($keys, array_keys($array));하는 운동에 참여 좀 덜인지 부하가 있기 때문에 array_flip들.
— moopet

193

다음은 많은 수의 키를 확인하려는 경우에도 확장 가능한 솔루션입니다.

<?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!
}

왜 이것이 downvoted되었는지 알고 싶습니다. afaik array_intersect_key가 C로 구현되고 루프가 필요하지 않기 때문에 더 빠릅니다
— Erfan

실제로 꽤 영리하고 잘했습니다. 읽기는 조금 어렵습니다.
— Jon z

고마워요 :) 이상하게도 PHP에는이 작업을 수행하는 내장 함수가 없습니다. 매우 일반적입니다. 이를 수행하는 수많은 사용자 입력 유효성 검사 클래스가 있지만 대부분의 사용 사례에서 과잉 사용
— Erfan

12
참으로 영리한 해결책이지만 간단한 것보다 정말 느립니다 (내 상자에서 약 50 % 느립니다).```$ ok = true; foreach ($ 필수 $ field) {if (! array_key_exists ($ field, $ data)) $ ok = false; }
— Ozh dec

@Ozh를 제외하고 array_key_exists는 isset보다 느립니다
— iautomation

34

의외로 array_keys_exist존재하지 않는다?! 그 사이에이 일반적인 작업에 대한 한 줄 표현을 알아 내기 위해 약간의 공간이 남습니다. 쉘 스크립트 나 다른 작은 프로그램을 생각하고 있습니다.

참고 : 다음 각 솔루션 […]은 PHP 5.4 이상에서 사용 가능한 간결한 배열 선언 구문을 사용합니다.

array_diff + array_keys

if (0 === count(array_diff(['story', 'message', '…'], array_keys($source)))) {
  // all keys found
} else {
  // not all
}

( Kim Stacks에 대한 모자 팁 )

이 접근 방식은 제가 찾은 것 중 가장 간단합니다. array_diff()인수 2에 없는 인수 1에있는 항목의 배열을 리턴합니다 . 따라서 빈 배열은 모든 키가 발견되었음을 나타냅니다. PHP 5.5에서는 0 === count(…)간단하게 empty(…).

array_reduce + 설정 해제

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
}

읽기 어렵고 변경하기 쉽습니다. array_reduce()콜백을 사용하여 배열을 반복하여 값에 도달합니다. $initial값에 관심이있는 $in키를 입력 한 다음 소스에서 찾은 키를 제거하면 모든 키가 발견되면 0 요소로 끝날 것으로 예상 할 수 있습니다.

우리가 관심이있는 키가 하단 라인에 잘 맞기 때문에 구성을 수정하기 쉽습니다.

배열 _ 필터 및 배열 내

if (2 === count(array_filter(array_keys($source), function($key) { 
        return in_array($key, ['story', 'message']); }
    )))
{
  // all keys found
} else {
  // not all
}

array_reduce솔루션 보다 작성하기가 더 간단 하지만 편집하기가 약간 더 까다 롭습니다. array_filter또한 콜백에서 true (항목을 새 배열로 복사) 또는 false (복사하지 않음)를 반환하여 필터링 된 배열을 만들 수있는 반복 콜백입니다. 문제는 2예상하는 항목 수를 변경해야한다는 것입니다.

이것은 더 오래 지속될 수 있지만 터무니없는 가독성에 가깝습니다.

$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
}

3
작은 세트의 경우 차이는 무시할 수 있습니다. 대규모 데이터 세트를 처리하는 라이브러리 / 프레임 워크를 작성하는 경우 조기 최적화보다는 병목 현상을 찾기 위해 각 유닛의 성능을 테스트해야합니다.
— Mark Fox

16

나에게 가장 쉬운 방법은 다음과 같습니다.

$required = array('a','b','c','d');

$values = array(
    'a' => '1',
    'b' => '2'
);

$missing = array_diff_key(array_flip($required), $values);

인쇄물:

Array(
    [c] => 2
    [d] => 3
)

또한 정확히 누락 된 키를 확인할 수 있습니다. 이는 오류 처리에 유용 할 수 있습니다.


이것이 내가 여기에 온 것입니다!
— eNeMetcH

8

한 가지 더 가능한 해결책 :

if (!array_diff(['story', 'message'], array_keys($array))) {
    // OK: all the keys are in $array
} else {
   // FAIL: some keys are not
}

7

위의 솔루션은 영리하지만 매우 느립니다. isset이있는 간단한 foreach 루프는 array_intersect_key솔루션 보다 두 배 이상 빠릅니다 .

function array_keys_exist($keys, $array){
    foreach($keys as $key){
        if(!array_key_exists($key, $array))return false;
    }
    return true;
}

(1000000 반복의 경우 344ms 대 768ms)


isset은 [ 'key'=> null]이면 false를 반환하고 때로는 null 값을 가진 배열이 있습니다. 대신는 isset array_key_exists을 사용해야합니다
— j4r3k

false( 이 경우 false재정 의) 조기 반환 때문에 여기서 반대를 사용해야했습니다 true. 그럼, 내 요구에 작동하는 것은 foreach ($keys as $key) { if (array_key_exists($key, $array)) { return true; }} return false;경우에 내 요구했다 any배열의 키가 ... 다른 배열에 존재
— 제프를

1
나는 백만 개의 키에 대해 +/- 400ms를 "매우 느리다"라고 부르지 않을 것이지만 나는 인간 일뿐입니다!
— colonelclick

3

다음과 같은 것이 있다면 :

$stuff = array();
$stuff[0] = array('story' => 'A story', 'message' => 'in a bottle');
$stuff[1] = array('story' => 'Foo');

간단하게 count()다음과 같이 할 수 있습니다 .

foreach ($stuff as $value) {
  if (count($value) == 2) {
    // story and message
  } else {
    // only story
  }
}

이 배열 키만 있고 다른 것은 없다는 것을 알고있는 경우에만 작동합니다.

array_key_exists () 사용은 한 번에 하나의 키만 확인하는 것을 지원하므로 두 가지 모두 별도로 확인해야합니다.

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()키가 배열에 있지만 실제 함수이고 입력 할 것이 많으면 true를 반환합니다. 언어 구성 isset()은 테스트 된 값이 NULL 인 경우를 제외하고 거의 동일합니다.

foreach ($stuff as $value) {
  if (isset($value['story']) && isset($value['message']) {
    // story and message
  } else {
    // either one or both keys missing
  }
}

또한 isset을 사용하면 한 번에 여러 변수를 확인할 수 있습니다.

foreach ($stuff as $value) {
  if (isset($value['story'], $value['message']) {
    // story and message
  } else {
    // either one or both keys missing
  }
}

이제 설정된 항목에 대한 테스트를 최적화하려면 다음 "if"를 사용하는 것이 좋습니다.

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
  }
}

3

이것에 대해 :

isset($arr['key1'], $arr['key2']) 

둘 다 null이 아닌 경우에만 true를 반환합니다.

null이면 키가 배열에 없습니다.


1
$arr['key1']또는 값 $arr['key2']이 null인 경우 코드는 키가 여전히 존재합니다.
— Xorifelse

나는 그것을 @Xorifelse에서 테스트 해보기 쓴 테스트를 하고 내가 틀렸다면 수정하시기 바랍니다. 참고 : 그 당시에는 PHP 5.6. * 버전 만 알고 있었기 때문에 해당 버전 만 사용했습니다.
— 데이비드 Dutkovsky

그 코드는 무엇을 달성하려고합니까? foreach루프를 사용하지 않는 이유는 무엇 입니까?
— Xorifelse

isset기능이 내 뜻대로 작동 한다는 증명을 추가하고 싶었지만 이제는 당신이 옳았다는 것을 깨닫고 키는 여전히 배열에 남아 있으므로 내 대답이 올바르지 않습니다. 피드백에 감사드립니다. 예, 사용할 수 있습니다 foreach.
— 데이비드 Dutkovsky

3

나는 이런 것을 자주 사용합니다

$wantedKeys = ['story', 'message'];
$hasWantedKeys = count(array_intersect(array_keys($source), $wantedKeys)) > 0

또는 원하는 키의 값을 찾으려면

$wantedValues = array_intersect_key($source, array_fill_keys($wantedKeys, 1))

2

이 시도

$required=['a','b'];$data=['a'=>1,'b'=>2];
if(count(array_intersect($required,array_keys($data))>0){
    //a key or all keys in required exist in data
 }else{
    //no keys found
  }

1

이것은 내가 클래스 내에서 사용하기 위해 작성한 함수입니다.

<?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 />";
}

배열에 여러 키가 모두 존재하는지 확인해야한다고 가정합니다. 하나 이상의 키와 일치하는 것을 찾고 있다면 다른 기능을 제공 할 수 있도록 알려주세요.

여기 코드 패드 http://codepad.viper-7.com/AKVPCH


1
해결책은 괜찮지 만 멋진 한 줄 보석이 ​​묻혀 있습니다.if (0 === count(array_diff(['key1','key2','key3'], array_keys($lookIn)))) { // all keys exist } else { // nope }
— Mark Fox

당신이 쓴 것은 사실입니다. 장황하지만 내 기능이 더 읽기 쉽다는 것을 알았습니다. 물론 나는 착각 할 수있다. 내 대답에 대해 의견을 보내 주셔서 감사합니다. 나는 새로운 것을 배운다.
— Kim Stacks

1

도움이 되었기를 바랍니다:

function array_keys_exist($searchForKeys = array(), $inArray = array()) {
    $inArrayKeys = array_keys($inArray);
    return count(array_intersect($searchForKeys, $inArrayKeys)) == count($searchForKeys); 
}

1

이것은 오래되었고 아마도 묻히게 될 것이지만 이것이 나의 시도입니다.

@Ryan과 비슷한 문제가 있습니다. 적어도 1 키 배열이라면 어떤 경우에는, I에서만 확인이 필요하고, 경우에 따라, 모든 필요한 존재한다.

그래서이 함수를 작성했습니다.

/**
 * 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;
}

이 쓰기 복수하는 것보다 훨씬 쉬웠다 ||및 &&블록.


0

작동하지 않습니까?

array_key_exists('story', $myarray) && array_key_exists('message', $myarray)

2
상수는 배열이 될 수 없습니다 ... :)
— Sven

자동 완성 IDE를 검사하는 슈퍼 코드를 작성하지 않을 때는 항상 $를 잊어 버립니다. =)
— Kiwi

0
<?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;
}

// 데모 실행

$key = 'a,b,c';
$array = array('a'=>'aaaa','b'=>'ccc','c'=>'eeeee');

var_dump( check_keys_exists($key, $array));

0

나는 그것이 나쁜 생각인지 확실하지 않지만 매우 간단한 foreach 루프를 사용하여 여러 배열 키를 확인합니다.

// 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]);
    }
} 

0
// sample data
$requiredKeys = ['key1', 'key2', 'key3'];
$arrayToValidate = ['key1' => 1, 'key2' => 2, 'key3' => 3];

function keysExist(array $requiredKeys, array $arrayToValidate) {
    if ($requiredKeys === array_keys($arrayToValidate)) {
        return true;
    }

    return false;
}

0
$myArray = array('key1' => '', 'key2' => '');
$keys = array('key1', 'key2', 'key3');
$keyExists = count(array_intersect($keys, array_keys($myArray)));

$ myArray에 $ keys 배열의 키가 있으므로 true를 반환합니다.


0

이것이 사용될 수있는 것

//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;

2에 대한 검사에 유의하십시오. 검색하려는 값이 다른 경우 변경할 수 있습니다.

이 솔루션은 효율적이지 않을 수 있지만 작동합니다!

업데이트

하나의 지방 기능에서 :

 /**
 * 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)));

}

예를 들면 다음과 같습니다.

$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);

도움이 되었기를 바랍니다 :)


0

나는 일반적으로 내 게시물을 확인하는 기능을 사용하며이 질문에 대한 답변이기도하므로 게시하겠습니다.

내 함수를 호출하려면 다음과 같이 2 배열을 사용합니다.

validatePost(['username', 'password', 'any other field'], $_POST))

내 기능은 다음과 같습니다.

 function validatePost($requiredFields, $post)
    {
        $validation = [];

        foreach($requiredFields as $required => $key)
        {
            if(!array_key_exists($key, $post))
            {
                $validation['required'][] = $key;
            }
        }

        return $validation;
    }

이것은 이것을 출력합니다

"필수": [ "사용자 이름", "비밀번호", "기타 필드"]

따라서이 함수가하는 일은 게시 요청의 모든 누락 된 필드를 확인하고 반환하는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.