다차원 어레이를 평평하게 하는 방법
PHP에서는 (bi/multi)차원 배열을 재귀나 참조를 사용하지 않고 평평하게 하는 것이 가능한가요?
요, 키 무시하기 위해서, 키 하기 위해서, 키 무시하기 위해서 그런 을 하고 array_map()
★★★★★★★★★★★★★★★★★」array_values()
.
PHP 5.3에서 가장 짧은 해결책은 새로운 폐쇄 구문인 것 같습니다.
function flatten(array $array) {
$return = array();
array_walk_recursive($array, function($a) use (&$return) { $return[] = $a; });
return $return;
}
SPL(Standard PHP Library)을 사용하여 재귀를 "숨길" 수 있습니다.
$a = array(1,2,array(3,4, array(5,6,7), 8), 9);
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($a));
foreach($it as $v) {
echo $v, " ";
}
인쇄하다
1 2 3 4 5 6 7 8 9
5.6에서는 PHP 5.6을 사용하여 2차원 수 .array_merge
한 후,...
.이치노
array_merge(...$a);
이것은, 관련지어 어레이의 컬렉션에서도 동작합니다.
$a = [[10, 20], [30, 40]];
$b = [["x" => "A", "y" => "B"], ["y" => "C", "z" => "D"]];
print_r(array_merge(...$a));
print_r(array_merge(...$b));
Array
(
[0] => 10
[1] => 20
[2] => 30
[3] => 40
)
Array
(
[x] => A
[y] => C
[z] => D
)
PHP 8.0 이하에서는, 외부 어레이에 숫자 이외의 키가 있는 경우는, 어레이 언팩이 동작하지 않습니다.문자열 키를 사용하여 배열 압축을 푸는 기능은 PHP 8.1에서 사용할 수 있습니다.8.0 이하를 서포트하려면 , 다음의 URL 에 문의해 주세요.array_values
번째
$c = ["a" => ["x" => "A", "y" => "B"], "b" => ["y" => "C", "z" => "D"]];
print_r(array_merge(...array_values($c)));
Array
(
[x] => A
[y] => C
[z] => D
)
업데이트: @MohamedGharib의 코멘트를 기반으로 합니다.
외부 있으면 오류가 합니다. 외부 배열이 비어 있기 때문입니다.array_merge
0으로 하다빈 배열을 첫 번째 인수로 추가하면 이를 피할 수 있습니다.
array_merge([], ...$a);
2차원 어레이용 솔루션
다음을 시도해 보십시오.
$array = your array
$result = call_user_func_array('array_merge', $array);
echo "<pre>";
print_r($result);
편집: 8월 21일-13일
다음은 다차원 어레이에 적합한 솔루션입니다.
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);
참고 자료: http://php.net/manual/en/function.call-user-func-array.php
(요청한 대로) 재귀 없이 평탄하게 하려면 스택을 사용할 수 있습니다.자연스럽게 이 기능을 자체 기능으로 사용할 수 있습니다.array_flatten
하다
function array_flatten(array $array)
{
$flat = array(); // initialize return array
$stack = array_values($array); // initialize stack
while($stack) // process stack until done
{
$value = array_shift($stack);
if (is_array($value)) // a value to further process
{
array_unshift($stack, ...$value);
}
else // a value to take
{
$flat[] = $value;
}
}
return $flat;
}
요소는 순서대로 처리됩니다.하위 요소는 스택 위로 이동되므로 다음으로 처리됩니다.
키를 고려하는 것도 가능하지만 스택을 처리하려면 다른 전략이 필요합니다.서브어레이에서 중복될 수 있는 키를 처리해야 하기 때문에 필요합니다.관련 질문에서도 비슷한 답변: PHP 키를 유지하면서 다차원 어레이를 살펴봅니다.
확실히는 모르지만, 과거에 이것을 테스트한 적이 있습니다.RecurisiveIterator
에서는 재귀가 사용되고 있기 때문에, 실제로 무엇이 필요한지에 따라 다릅니다.스택을 기반으로 재귀 반복기를 만들 수도 있습니다.
foreach(new FlatRecursiveArrayIterator($array) as $key => $value)
{
echo "** ($key) $value\n";
}
이 스택을 실장하는 것은 지금까지 달성하지 못했습니다.RecursiveIterator
좋은 생각인 것 같아요
이것은 폴드이므로 array_reduce를 사용할 수 있습니다.
array_reduce($my_array, 'array_merge', array());
편집: 이것은 임의의 수의 레벨을 평평하게 하도록 구성할 수 있습니다.이것은, 다음의 몇개의 방법으로 실시할 수 있습니다.
// Reduces one level
$concat = function($x) { return array_reduce($x, 'array_merge', array()); };
// We can compose $concat with itself $n times, then apply it to $x
// This can overflow the stack for large $n
$compose = function($f, $g) {
return function($x) use ($f, $g) { return $f($g($x)); };
};
$identity = function($x) { return $x; };
$flattenA = function($n) use ($compose, $identity, $concat) {
return function($x) use ($compose, $identity, $concat, $n) {
return ($n === 0)? $x
: call_user_func(array_reduce(array_fill(0, $n, $concat),
$compose,
$identity),
$x);
};
};
// We can iteratively apply $concat to $x, $n times
$uncurriedFlip = function($f) {
return function($a, $b) use ($f) {
return $f($b, $a);
};
};
$iterate = function($f) use ($uncurriedFlip) {
return function($n) use ($uncurriedFlip, $f) {
return function($x) use ($uncurriedFlip, $f, $n) {
return ($n === 0)? $x
: array_reduce(array_fill(0, $n, $f),
$uncurriedFlip('call_user_func'),
$x);
}; };
};
$flattenB = $iterate($concat);
// Example usage:
$apply = function($f, $x) {
return $f($x);
};
$curriedFlip = function($f) {
return function($a) use ($f) {
return function($b) use ($f, $a) {
return $f($b, $a);
}; };
};
var_dump(
array_map(
call_user_func($curriedFlip($apply),
array(array(array('A', 'B', 'C'),
array('D')),
array(array(),
array('E')))),
array($flattenA(2), $flattenB(2))));
물론 루프를 사용할 수도 있지만 문제는 array_map 또는 array_values 행에 따라 조합 함수를 요구합니다.
직설적이고 한 줄짜리 답변입니다.
function flatten_array(array $array)
{
return iterator_to_array(
new \RecursiveIteratorIterator(new \RecursiveArrayIterator($array)));
}
사용방법:
$array = [
'name' => 'Allen Linatoc',
'profile' => [
'age' => 21,
'favourite_games' => [ 'Call of Duty', 'Titanfall', 'Far Cry' ]
]
];
print_r( flatten_array($array) );
출력(Sy 단위)SH):
Array
(
[name] => Allen Linatoc
[age] => 21
[0] => Call of Duty
[1] => Titanfall
[2] => Far Cry
)
이제 열쇠를 어떻게 다루느냐에 달렸어요.건배.
편집(2017-03-01)
명확하게 하기 위해서, 이 조작은 키(숫자 키도 포함)를 보존하기 때문에, 같은 키를 가지는 값은 없어집니다.예를들면
$array = ['a',['b','c']]
된다Array ([0] => b, [1] => c )
.그'a'
로 인해 손실되었습니다.'b'
열쇠도 가지고 있다0
Svish의 답변 인용:
두 번째 매개 변수로 false를 추가합니다.
($use_keys)
반복기_to_array 호출에 대한
재귀를 사용합니다.이것이 얼마나 복잡하지 않은지 보는 순간, 재귀에 대한 두려움이 사라지길 바랍니다.
function flatten($array) {
if (!is_array($array)) {
// nothing to do if it's not an array
return array($array);
}
$result = array();
foreach ($array as $value) {
// explode the sub-array, and add the parts
$result = array_merge($result, flatten($value));
}
return $result;
}
$arr = array('foo', array('nobody', 'expects', array('another', 'level'), 'the', 'Spanish', 'Inquisition'), 'bar');
echo '<ul>';
foreach (flatten($arr) as $value) {
echo '<li>', $value, '</li>';
}
echo '<ul>';
출력:
<ul><li>foo</li><li>nobody</li><li>expects</li><li>another</li><li>level</li><li>the</li><li>Spanish</li><li>Inquisition</li><li>bar</li><ul>
2차원 어레이만 평탄화:
$arr = [1, 2, [3, 4]];
$arr = array_reduce($arr, function ($a, $b) {
return array_merge($a, (array) $b);
}, []);
// Result: [1, 2, 3, 4]
이 솔루션은 재귀적이지 않습니다.요소의 순서는 다소 혼재합니다.
function flatten($array) {
$return = array();
while(count($array)) {
$value = array_shift($array);
if(is_array($value))
foreach($value as $sub)
$array[] = $sub;
else
$return[] = $value;
}
return $return;
}
어레이를 평탄화하기 위한 Larabel 도우미는 Arr:: flatten()입니다.
저는 이것이 돌연변이나 낯선 클래스를 사용하지 않는 가장 깨끗한 해결책이라고 생각합니다.
<?php
function flatten($array)
{
return array_reduce($array, function($acc, $item){
return array_merge($acc, is_array($item) ? flatten($item) : [$item]);
}, []);
}
// usage
$array = [1, 2, [3, 4], [5, [6, 7]], 8, 9, 10];
print_r(flatten($array));
다음과 같은 간단한 기능을 사용해 보십시오.
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;
}
여기서부터:
array (
'und' =>
array (
'profiles' =>
array (
0 =>
array (
'commerce_customer_address' =>
array (
'und' =>
array (
0 =>
array (
'first_name' => 'First name',
'last_name' => 'Last name',
'thoroughfare' => 'Address 1',
'premise' => 'Address 2',
'locality' => 'Town/City',
'administrative_area' => 'County',
'postal_code' => 'Postcode',
),
),
),
),
),
),
)
다음과 같은 것이 있습니다.
array (
'first_name' => 'First name',
'last_name' => 'Last name',
'thoroughfare' => 'Address 1',
'premise' => 'Address 2',
'locality' => 'Town/City',
'administrative_area' => 'County',
'postal_code' => 'Postcode',
)
Ouzo goodies로 할 수 있습니다.
$result = Arrays::flatten($multidimensional);
참조: 여기
열쇠도 보관하고 싶다면 그것이 해결책입니다.
function flatten(array $array) {
$return = array();
array_walk_recursive($array, function($value, $key) use (&$return) { $return[$key] = $value; });
return $return;
}
유감스럽게도 중간 키를 사용하지 않고 최종 중첩된 배열만 출력합니다.예를 들어 다음과 같습니다.
$array = array(
'sweet' => array(
'a' => 'apple',
'b' => 'banana'),
'sour' => 'lemon');
print_r(flatten($fruits));
출력:
Array
(
[a] => apple
[b] => banana
[sour] => lemon
)
문제는 소스 어레이와 대상 어레이를 모두 참조로 전달하는 것입니다.
function flatten_array(&$arr, &$dst) {
if(!isset($dst) || !is_array($dst)) {
$dst = array();
}
if(!is_array($arr)) {
$dst[] = $arr;
} else {
foreach($arr as &$subject) {
flatten_array($subject, $dst);
}
}
}
$recursive = array('1', array('2','3',array('4',array('5','6')),'7',array(array(array('8'),'9'),'10')));
echo "Recursive: \r\n";
print_r($recursive);
$flat = null;
flatten_array($recursive, $flat);
echo "Flat: \r\n";
print_r($flat);
// If you change line 3 to $dst[] = &$arr; , you won't waste memory,
// since all you're doing is copying references, and imploding the array
// into a string will be both memory efficient and fast:)
echo "String:\r\n";
echo implode(',',$flat);
재귀가 정말 싫다면...대신 이동해 보세요:)
$a = array(1,2,array(3,4, array(5,6,7), 8), 9);
$o = [];
for ($i=0; $i<count($a); $i++) {
if (is_array($a[$i])) {
array_splice($a, $i+1, 0, $a[$i]);
} else {
$o[] = $a[$i];
}
}
주의: 이 간단한 버전에서는 어레이 키를 지원하지 않습니다.
재귀 발생기를 사용하는 것은 어떻습니까?https://ideone.com/d0TXCg
<?php
$array = [
'name' => 'Allen Linatoc',
'profile' => [
'age' => 21,
'favourite_games' => [ 'Call of Duty', 'Titanfall', 'Far Cry' ]
]
];
foreach (iterate($array) as $item) {
var_dump($item);
};
function iterate($array)
{
foreach ($array as $item) {
if (is_array($item)) {
yield from iterate($item);
} else {
yield $item;
}
}
}
PHP v7.4부터는 확산 연산자를 사용하여 어레이를 병합할 수 있습니다.심플하고 효과적입니다.
$flatArr = array_merge(...$originalArray);
/**
* For merging values of a multidimensional array into one
*
* $array = [
* 0 => [
* 0 => 'a1',
* 1 => 'b1',
* 2 => 'c1',
* 3 => 'd1'
* ],
* 1 => [
* 0 => 'a2',
* 1 => 'b2',
* 2 => 'c2',
* ]
* ];
*
* becomes :
*
* $array = [
* 0 => 'a1',
* 1 => 'b1',
* 2 => 'c1',
* 3 => 'd1',
* 4 => 'a2',
* 5 => 'b2',
* 6 => 'c2',
*
* ]
*/
array_reduce
(
$multiArray
, function ($lastItem, $currentItem) {
$lastItem = $lastItem ?: array();
return array_merge($lastItem, array_values($currentItem));
}
);
이것은, 다음의 방법으로 실현할 수 있습니다.array_walk_recursive
$a = array(1,2,array(3,4, array(5,6,7), 8), 9);
array_walk_recursive($a, function($v) use (&$r){$r[]=$v;});
print_r($r);
작업 예:- https://3v4l.org/FpIrG
php 5.2의 경우
function flatten(array $array) {
$result = array();
if (is_array($array)) {
foreach ($array as $k => $v) {
if (is_array($v)) {
$result = array_merge($result, flatten($v));
} else {
$result[] = $v;
}
}
}
return $result;
}
이 버전에서는 딥, 슬림 또는 특정 수의 레벨을 수행할 수 있습니다.
/**
* @param array|object $array array of mixed values to flatten
* @param int|boolean $level 0:deep, 1:shallow, 2:2 levels, 3...
* @return array
*/
function flatten($array, $level = 0) {
$level = (int) $level;
$result = array();
foreach ($array as $i => $v) {
if (0 <= $level && is_array($v)) {
$v = flatten($v, $level > 1 ? $level - 1 : 0 - $level);
$result = array_merge($result, $v);
} elseif (is_int($i)) {
$result[] = $v;
} else {
$result[$i] = $v;
}
}
return $result;
}
이 안에 있는 암호가 무서워 보이거든요여기에서는 다차원 배열을 html 형식의 호환 구문으로도 변환하지만 읽기 쉬운 함수가 있습니다.
/**
* Flattens a multi demensional array into a one dimensional
* to be compatible with hidden html fields.
*
* @param array $array
* Array in the form:
* array(
* 'a' => array(
* 'b' => '1'
* )
* )
*
* @return array
* Array in the form:
* array(
* 'a[b]' => 1,
* )
*/
function flatten_array($array) {
// Continue until $array is a one-dimensional array.
$continue = TRUE;
while ($continue) {
$continue = FALSE;
// Walk through top and second level of $array and move
// all values in the second level up one level.
foreach ($array as $key => $value) {
if (is_array($value)) {
// Second level found, therefore continue.
$continue = TRUE;
// Move each value a level up.
foreach ($value as $child_key => $child_value) {
$array[$key . '[' . $child_key . ']'] = $child_value;
}
// Remove second level array from top level.
unset($array[$key]);
}
}
}
return $array;
}
이것에 대해 매우 깨끗한 솔루션을 찾고 있는 유저에게, 다음과 같은 옵션이 있습니다.
다양한 주요 가치 구성을 가진 어레이를 선택:
$test_array = array(
array('test' => 0, 0, 0, 0),
array(0, 0, 'merp' => array('herp' => 'derp'), 0),
array(0, 0, 0, 0),
array(0, 0, 0, 0)
);
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($test_array));
var_dump( iterator_to_array($it, false) ) ;
그러면 각 어레이에서 값만 가져와 단일 플랫 어레이가 반환됩니다.
결과 값 출력:
0 0 0 0 0 0 derp 0 0 0 0 0 0 0 0 0
중간 키를 유지하는 경우:
function flattenArray(array &$result, $value, string $key = "")
{
if (!is_array($value)) {
$result[$key] = $value;
return $result;
}
foreach ($value as $subKey => $subArray) {
$newKey = $key !== "" ? $key . "_" . $subKey : $subKey;
flattenArray($result, $subArray, $newKey);
}
return $result;
}
$nestedArray = [
"name" => "John",
"pets" => [
["id" => 1, "name" => "snooop"],
["id" => 2, "name" => "medor"],
],
"job" => ["title" => "developper"],
];
$intermediateResult = [];
$flattened = flattenArray($intermediateResult, $nestedArray);
var_dump($flattened);
다음과 같이 출력됩니다.
array(6) {
["name"]=>
string(4) "John"
["pets_0_id"]=>
int(1)
["pets_0_name"]=>
string(6) "snooop"
["pets_1_id"]=>
int(2)
["pets_1_name"]=>
string(5) "medor"
["job_title"]=>
string(10) "developper"
}
https://ideone.com/KXLtzZ#stdout 를 참조해 주세요.
HTML 입력 포맷으로 PHP 다차원 배열을 표현해야 했습니다.
$test = [
'a' => [
'b' => [
'c' => ['a', 'b']
]
],
'b' => 'c',
'c' => [
'd' => 'e'
]
];
$flatten = function ($input, $parent = []) use (&$flatten) {
$return = [];
foreach ($input as $k => $v) {
if (is_array($v)) {
$return = array_merge($return, $flatten($v, array_merge($parent, [$k])));
} else {
if ($parent) {
$key = implode('][', $parent) . '][' . $k . ']';
if (substr_count($key, ']') != substr_count($key, '[')) {
$key = preg_replace('/\]/', '', $key, 1);
}
} else {
$key = $k;
}
$return[$key] = $v;
}
}
return $return;
};
die(var_dump( $flatten($test) ));
array(4) {
["a[b][c][0]"]=>
string(1) "a"
["a[b][c][1]"]=>
string(1) "b"
["b"]=>
string(1) "c"
["c[d]"]=>
string(1) "e"
}
객체 배열이 있고 노드를 사용하여 평탄하게 만들려면 다음 함수를 사용하십시오.
function objectArray_flatten($array,$childField) {
$result = array();
foreach ($array as $node)
{
$result[] = $node;
if(isset($node->$childField))
{
$result = array_merge(
$result,
objectArray_flatten($node->$childField,$childField)
);
unset($node->$childField);
}
}
return $result;
}
다음은 참조를 사용한 솔루션입니다.
function arrayFlatten($array_in, &$array_out){
if(is_array($array_in)){
foreach ($array_in as $element){
arrayFlatten($element, $array_out);
}
}
else{
$array_out[] = $array_in;
}
}
$arr1 = array('1', '2', array(array(array('3'), '4', '5')), array(array('6')));
arrayFlatten($arr1, $arr2);
echo "<pre>";
print_r($arr2);
echo "</pre>";
<?php
//recursive solution
//test array
$nested_array = [[1,2,[3]],4,[5],[[[6,[7=>[7,8,9,10]]]]]];
/*-----------------------------------------
function call and return result to an array
------------------------------------------*/
$index_count = 1;
$flatered_array = array();
$flatered_array = flat_array($nested_array, $index_count);
/*-----------------------------------------
Print Result
-----------------------------------------*/
echo "<pre>";
print_r($flatered_array);
/*-----------------------------------------
function to flaten an array
-----------------------------------------*/
function flat_array($nested_array, & $index_count, & $flatered_array) {
foreach($nested_array AS $key=>$val) {
if(is_array($val)) {
flat_array($val, $index_count, $flatered_array);
}
else {
$flatered_array[$index_count] = $val;
++$index_count;
}
}
return $flatered_array;
}
?>
언급URL : https://stackoverflow.com/questions/1319903/how-to-flatten-a-multidimensional-array
'programing' 카테고리의 다른 글
MySQL에서 이 인덱스를 삭제하는 방법 (0) | 2022.09.30 |
---|---|
문자열에 JavaScript의 하위 문자열 배열 텍스트가 포함되어 있는지 확인하는 방법 (0) | 2022.09.30 |
음수를 양수로 만드는 방법 (0) | 2022.09.30 |
NO_BACKSLASH_ESCAPES 옵션이 활성화 되어 있을 때 리터럴 퍼센트 부호를 이스케이프하려면 어떻게 해야 합니까? (0) | 2022.09.30 |
1개의 테이블에서 생성된 키를 1개의 요청으로 일괄 처리하여 2번째 테이블에 삽입합니다. (0) | 2022.09.30 |