PHP에서 다차원 배열을 단순 배열로 "평탄화"하는 방법은 무엇입니까?
아마도 초보 질문 일 수 있지만 이미 문서화를 더 오래 진행하고 있으며 해결책을 찾을 수 없습니다. 나는 각 차원에 대해 내파를 사용할 수 있다고 생각한 다음 그 문자열을 다시 결합하여 str_split
새로운 간단한 배열을 만들 수 있습니다. 그러나 조인 패턴이 값에 없는지 여부를 알 수 없으므로 str_split
원래 값 을 수행 한 후에 는 손상 될 수 있습니다.
combine($array1, $array2)
다차원 배열 내부의 배열 과 같은 것이 있습니까?
<?php
$aNonFlat = array(
1,
2,
array(
3,
4,
5,
array(
6,
7
),
8,
9,
),
10,
11
);
$objTmp = (object) array('aFlat' => array());
array_walk_recursive($aNonFlat, create_function('&$v, $k, &$t', '$t->aFlat[] = $v;'), $objTmp);
var_dump($objTmp->aFlat);
/*
array(11) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
[7]=>
int(8)
[8]=>
int(9)
[9]=>
int(10)
[10]=>
int(11)
}
*/
?>
PHP 5.5.9-1ubuntu4.24 (cli)로 테스트 됨 (빌드 : 2018 년 3 월 16 일 12:32:06)
$array = your array
$result = call_user_func_array('array_merge', $array);
echo "<pre>";
print_r($result);
참조 : http://php.net/manual/en/function.call-user-func-array.php
다음은 또 다른 솔루션입니다 (다차원 배열로 작동).
function array_flatten($array) {
$return = array();
foreach ($array as $key => $value) {
if (is_array($value)){ $return = array_merge($return, array_flatten($value));}
else {$return[$key] = $value;}
}
return $return;
}
$array = Your array
$result = array_flatten($array);
echo "<pre>";
print_r($result);
이것은 사용하기 매우 쉬운 한 줄입니다.
$result = array();
array_walk_recursive($original_array,function($v) use (&$result){ $result[] = $v; });
익명의 기능 / 폐쇄 내부에서 이해하기 매우 쉽습니다. $v
귀하의 $original_array
.
// $array = your multidimensional array
$flat_array = array();
foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array)) as $k=>$v){
$flat_array[$k] = $v;
}
또한 문서화 됨 : http://www.phpro.org/examples/Flatten-Array.html
function flatten_array($array, $preserve_keys = 0, &$out = array()) {
# Flatten a multidimensional array to one dimension, optionally preserving keys.
#
# $array - the array to flatten
# $preserve_keys - 0 (default) to not preserve keys, 1 to preserve string keys only, 2 to preserve all keys
# $out - internal use argument for recursion
foreach($array as $key => $child)
if(is_array($child))
$out = flatten_array($child, $preserve_keys, $out);
elseif($preserve_keys + is_string($key) > 1)
$out[$key] = $child;
else
$out[] = $child;
return $out;
}
PHP의 사용자 의견 (간체)과 여기에있는 또 다른 방법 :
function array_flatten_recursive($array) {
if (!$array) return false;
$flat = array();
$RII = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach ($RII as $value) $flat[] = $value;
return $flat;
}
이 방법의 가장 큰 장점은 평면화하는 동안 필요한 경우 재귀의 깊이를 추적한다는 것입니다.
그러면 다음이 출력됩니다.
$array = array(
'A' => array('B' => array( 1, 2, 3)),
'C' => array(4, 5)
);
print_r(array_flatten_recursive($array));
#Returns:
Array (
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
비재 귀적 솔루션 (순서 파괴) :
function flatten($ar) {
$toflat = array($ar);
$res = array();
while (($r = array_shift($toflat)) !== NULL) {
foreach ($r as $v) {
if (is_array($v)) {
$toflat[] = $v;
} else {
$res[] = $v;
}
}
}
return $res;
}
PHP> = 5.3에서 Luc M의 답변 (첫 번째 답변)에 따라 다음과 같은 클로저를 사용할 수 있습니다.
array_walk_recursive($aNonFlat, function(&$v, $k, &$t){$t->aFlat[] = $v;}, $objTmp);
create_function ()을 사용할 때처럼 함수의 코드를 따옴표로 묶을 필요가 없기 때문에 이것을 좋아합니다.
PHP 7에서는 생성기 및 생성기 위임 ( yield from
)을 사용하여 배열을 평면화 할 수 있습니다.
function array_flatten_iterator (array $array) {
foreach ($array as $value) {
if (is_array($value)) {
yield from array_flatten_iterator($value);
} else {
yield $value;
}
}
}
function array_flatten (array $array) {
return iterator_to_array(array_flatten_iterator($array), false);
}
예:
$array = [
1,
2,
[
3,
4,
5,
[
6,
7
],
8,
9,
],
10,
11,
];
var_dump(array_flatten($array));
특별히 한 수준 이상으로 가지 않는 배열이있는 경우 (일반적인 사용 사례) array_merge
및 표시 연산자 를 사용할 수 있습니다 .
<?php
$notFlat = [[1,2],[3,4]];
$flat = array_merge(...$notFlat);
var_dump($flat);
산출:
array(4) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
}
splat 연산자는 배열의 배열을에 대한 인수로 배열 목록으로 효과적으로 변경합니다 array_merge
.
고차 함수 사용 (참고 : PHP 5.3에 등장한 인라인 익명 함수를 사용하고 있습니다 ) :
function array_flatten($array) {
return array_reduce(
$array,
function($prev, $element) {
if (!is_array($element))
$prev[] = $element;
else
$prev = array_merge($prev, array_flatten($element));
return $prev;
},
array()
);
}
chaos가 제출 한 이전 예제 함수를 기반으로 한 새로운 접근 방식으로 다중 배열에서 문자열 키를 덮어 쓰는 버그를 수정합니다.
# Flatten a multidimensional array to one dimension, optionally preserving keys.
# $array - the array to flatten
# $preserve_keys - 0 (default) to not preserve keys, 1 to preserve string keys only, 2 to preserve all keys
# $out - internal use argument for recursion
function flatten_array($array, $preserve_keys = 2, &$out = array(), &$last_subarray_found)
{
foreach($array as $key => $child)
{
if(is_array($child))
{
$last_subarray_found = $key;
$out = flatten_array($child, $preserve_keys, $out, $last_subarray_found);
}
elseif($preserve_keys + is_string($key) > 1)
{
if ($last_subarray_found)
{
$sfinal_key_value = $last_subarray_found . "_" . $key;
}
else
{
$sfinal_key_value = $key;
}
$out[$sfinal_key_value] = $child;
}
else
{
$out[] = $child;
}
}
return $out;
}
Example:
$newarraytest = array();
$last_subarray_found = "";
$this->flatten_array($array, 2, $newarraytest, $last_subarray_found);
/*consider $mArray as multidimensional array and $sArray as single dimensional array
this code will ignore the parent array
*/
function flatten_array2($mArray) {
$sArray = array();
foreach ($mArray as $row) {
if ( !(is_array($row)) ) {
if($sArray[] = $row){
}
} else {
$sArray = array_merge($sArray,flatten_array2($row));
}
}
return $sArray;
}
당신은 이것을 시도 할 수 있습니다 :
function flat_an_array($a)
{
foreach($a as $i)
{
if(is_array($i))
{
if($na) $na = array_merge($na,flat_an_array($i));
else $na = flat_an_array($i);
}
else $na[] = $i;
}
return $na;
}
배열 키를 잃어도 괜찮다면 다음과 같이 array_values ()를 활용하는 콜백으로 재귀 적 클로저를 사용하여 다차원 배열을 평면화하여이 콜백이 array_walk ()의 매개 변수인지 확인하십시오.
<?php
$array = [1,2,3,[5,6,7]];
$nu_array = null;
$callback = function ( $item ) use(&$callback, &$nu_array) {
if (!is_array($item)) {
$nu_array[] = $item;
}
else
if ( is_array( $item ) ) {
foreach( array_values($item) as $v) {
if ( !(is_array($v))) {
$nu_array[] = $v;
}
else
{
$callback( $v );
continue;
}
}
}
};
array_walk($array, $callback);
print_r($nu_array);
이전 예제의 한 가지 단점은 단순화 된 콜백과 함께 array_walk_recursive ()를 사용하는 다음 솔루션보다 훨씬 많은 코드를 작성해야한다는 것입니다.
<?php
$array = [1,2,3,[5,6,7]];
$nu_array = [];
array_walk_recursive($array, function ( $item ) use(&$nu_array )
{
$nu_array[] = $item;
}
);
print_r($nu_array);
라이브 코드 보기
이 예제는 다차원 배열에서 값을 추출하는 방법에 대한 세부 정보를 숨기는 이전 예제보다 선호됩니다. 확실히 반복이 발생하지만 재귀 또는 제어 구조가 수반되는지 여부에 관계없이 array.c 를 숙독해야 알 수 있습니다 . 함수형 프로그래밍은 결과를 얻는 것보다 입력과 출력에 초점을 맞추기 때문에, 분명히 고용주가 그러한 질문을 제기 할 때까지이면에서 반복이 어떻게 발생하는지에 대해 걱정할 필요가 없습니다.
비표준 PHP 라이브러리 (NSPL) 의 flatten 함수를 사용할 수 있습니다 . 배열 및 반복 가능한 데이터 구조와 함께 작동합니다.
assert([1, 2, 3, 4, 5, 6, 7, 8, 9] === flatten([[1, [2, [3]]], [[[4, 5, 6]]], 7, 8, [9]]));
간단한 접근 .. 재귀를 통해보기 ..
<?php
function flatten_array($simple){
static $outputs=array();
foreach ( $simple as $value)
{
if(is_array($value)){
flatten_array($value);
}
else{
$outputs[]=$value;
}
}
return $outputs;
}
$eg=['s'=>['p','n'=>['t']]];
$out=flatten_array($eg);
print_r($out);
?>
다단계 배열을 하나로 변환하는 간단한 방법을 찾았습니다. 배열을 URL 문자열로 변환하는 "http_build_query"함수를 사용합니다. 그런 다음 explode로 문자열을 분할하고 값을 디코딩합니다.
다음은 샘플입니다.
$converted = http_build_query($data);
$rows = explode('&', $converted);
$output = array();
foreach($rows AS $k => $v){
list($kk, $vv) = explode('=', $v);
$output[ urldecode($kk) ] = urldecode($vv);
}
return $output;
특정 키의 값에만 관심이있는 경우이 접근 방식이 유용 할 수 있습니다.
function valuelist($array, $array_column) {
$return = array();
foreach($array AS $row){
$return[]=$row[$array_column];
};
return $return;
};
예:
주어진 $ get_role_action =
array(3) {
[0]=>
array(2) {
["ACTION_CD"]=>
string(12) "ADD_DOCUMENT"
["ACTION_REASON"]=>
NULL
}
[1]=>
array(2) {
["ACTION_CD"]=>
string(13) "LINK_DOCUMENT"
["ACTION_REASON"]=>
NULL
}
[2]=>
array(2) {
["ACTION_CD"]=>
string(15) "UNLINK_DOCUMENT"
["ACTION_REASON"]=>
NULL
}
}
보다 $variables['role_action_list']=valuelist($get_role_action, 'ACTION_CD');
초래 :
$variables["role_action_list"]=>
array(3) {
[0]=>
string(12) "ADD_DOCUMENT"
[1]=>
string(13) "LINK_DOCUMENT"
[2]=>
string(15) "UNLINK_DOCUMENT"
}
여기에서 다음과 같이 값 조회를 수행 할 수 있습니다.
if( in_array('ADD_DOCUMENT', $variables['role_action_list']) ){
//do something
};
이 중 어느 것도 나를 위해 작동하지 않았으므로 직접 실행해야했습니다. 잘 작동합니다.
function arrayFlat($arr){
$out = '';
foreach($arr as $key => $value){
if(!is_array($value)){
$out .= $value.',';
}else{
$out .= $key.',';
$out .= arrayFlat($value);
}
}
return trim($out,',');
}
$result = explode(',',arrayFlat($yourArray));
echo '<pre>';
print_r($result);
echo '</pre>';
다차원 배열이 주어지고이를 1 차원으로 변환하는 경우 배열이있는 모든 값을 설정 해제하고이를 1 차원으로 저장하면됩니다. 예를 들면 다음과 같습니다.
function _flatten_array($arr) {
while ($arr) {
list($key, $value) = each($arr);
is_array($value) ? $arr = $value : $out[$key] = $value;
unset($arr[$key]);
}
return (array)$out;
}
'Programing' 카테고리의 다른 글
GET 매개 변수를 추가하여 URL 문자열 조작 (0) | 2020.10.28 |
---|---|
렌더링 중 발생한 예외 : java.lang.System.arraycopy (0) | 2020.10.28 |
Android EditText 힌트 크기 (0) | 2020.10.28 |
Git에서 폴더 구조로 수정 및 추가 된 파일 만 내보내기 (0) | 2020.10.28 |
인덱스로 std :: tuple 요소를 설정하는 방법은 무엇입니까? (0) | 2020.10.27 |