একটি বহুমাত্রিক অ্যারে কীভাবে ফ্ল্যাট করবেন?


259

পিএইচপি-তে কি পুনরাবৃত্তি বা রেফারেন্স ব্যবহার না করে একটি (দ্বি / বহু) মাত্রিক অ্যারে সমতল করা সম্ভব?

আমি শুধু মান আগ্রহী তাই কি উপেক্ষিত করা যেতে পারে, আমি লাইনে চিন্তা করছি array_map()এবং array_values()


17
কেন পুনরাবৃত্তি এড়ানো?
JorenB

5
প্রতারিত (বেশিরভাগই) stackoverflow.com/questions/526556/...
cletus

4
পুনরাবৃত্তি না করে আপনি নির্বিচারে গভীরভাবে অ্যারের সমস্ত উপাদানগুলির সাথে কিছু করতে পারবেন না (আপনি এটি পুনরাবৃত্তি হিসাবে ছদ্মবেশী করতে পারেন, তবে আলু, পোটাহাটো)) আপনি যদি কেবল নিজেরাই পুনরাবৃত্তি পরিচালনা কোডটি এড়াতে চান তবে dk2.php.net/ ব্যবহার করুন ম্যানুয়াল / এন / ফাংশন। অ্যারে -ওয়াক-রিকার্সিভ.পিএফপি একটি কলব্যাকের সাহায্যে উপাদানটি একটি উপলব্ধ অ্যারেতে যুক্ত করে (গ্লোবাল, ইউজারডাটা প্যারামিটার ব্যবহার করুন, এটি একটি শ্রেণিতে রাখুন এবং এটি উল্লেখ করুন)
মাইকেল ম্যাডসেন

@ জোরেনবি: আমি দেখতে চাই যে একটি বাস্তবায়ন সংরক্ষণাগারভুক্ত করা যেতে পারে।
অ্যালিক্স অ্যাক্সেল

এনএসপিএল থেকে সমতল ফাংশনটি দেখুন । আপনি এটির সাথে গভীরতাও নির্দিষ্ট করতে পারেন।
ইহোর বুর্লাঞ্চো

উত্তর:


276

পুনরাবৃত্তিটি "লুকিয়ে" রাখতে আপনি স্ট্যান্ডার্ড পিএইচপি লাইব্রেরি (এসপিএল) ব্যবহার করতে পারেন ।

$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 

351
আমি কি কেবলই 'রিকার্সিআইট্রেটিআইট্রেটার' মনে করি নিরীহ নাম?
নীলামো

45
এটি "আকর্ষণীয়" এর চেয়ে বেশি "যৌক্তিক"। জওজিএল, নোল বা আউজুরের মতো সব কিছুরই দুর্দান্ত নাম থাকতে পারে না :-)
ভলকারক

7
এটি শিশু হিসাবে খালি অ্যারেগুলির জন্য কাজ করবে না। তাদের পিতামাতা হিসাবে ফিরিয়ে দেওয়া হবে।
hakre

45
iterator_to_array($it, false)ভবিষ্যতের প্রয়োজনীয়তা এড়ানো।
অ্যালিক্স অ্যাক্সেল

3
অন্যরা যা উপস্থাপন করেছিল তার ভিত্তিতে আমি এই সামান্য সহায়ককে কারুকাজ করতে সক্ষম হয়েছি: function flatten($arr){ $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)); return iterator_to_array($it, true); }আশা করি এটি অন্যকে সহায়তা করে।
মাইক এস

295

পিএইচপি 5.3 হিসাবে সংক্ষিপ্ততম সমাধানটি array_walk_recursive()নতুন ক্লোজার্স সিনট্যাক্সের সাথে রয়েছে বলে মনে হচ্ছে :

function flatten(array $array) {
    $return = array();
    array_walk_recursive($array, function($a) use (&$return) { $return[] = $a; });
    return $return;
}

33
আপনি কীগুলি চাইলে ফাংশন সমতল (অ্যারে $ অ্যারে) {$ রিটার্ন = অ্যারে (); অ্যারে_ওয়াক_সামগ্রী ($ অ্যারে, ফাংশন ($ a, $ বি) ব্যবহার (& $ রিটার্ন) $ $ রিটার্ন [$ বি] = $ এ;}); প্রত্যাবর্তন }
ব্রেন্ডন-ভ্যান-হেইজেন 16

আপনি পিএইচপি 5.2 ব্যবহার করতে এটি আবার লিখতে পারেন?
অ্যালেক্স

2
@ অ্যালেক্স দুর্ভাগ্যক্রমে আপনার এই বাক্যটি useতৈরি করার জন্য বাক্য গঠন প্রয়োজন array_walk_recursiveকারণ এটি $userdataরেফারেন্সের মাধ্যমে by
চ্ছিক

1
এই জাতীয় অ্যারেগুলির জন্য দুর্দান্ত কাজের মতো দেখায় -> আদর্শ one.com / ডিএসএমএপিপি তবে এই জাতীয়গুলির জন্য নয় -> আদর্শ one.com/5 ক্লিটভা নাকি এটি আমার?
সেবাস্তিয়ান পিসকর্স্কি

2
@ সেবাস্তিয়ান পিসকর্স্কি এটি কারণ আপনার মানগুলি কীগুলির মতো আচরণ করা হচ্ছে, সুতরাং আপনি যখন আপনার নিজস্ব কী => মান জোড়াকে অ্যারের সাথে পরিচয় করিয়ে দেবেন সাথে সাথে প্রথম সূচী অবস্থানে আপনার অ্যারে মানগুলি কোনও মান ছাড়াই কী হিসাবে বিবেচিত হবে এবং কীগুলি রয়েছে অনন্য হতে, যেখানে দুটি চাবি মিলে যায়, আপনার মান একই কীতে যুক্ত হয়। একটি সহজ সমাধান হ'ল প্রথমে অ্যারে বাছাই করা। এটি পিএইচপি-র অন্তর্নিহিত আচরণ।
মার্টিন শট

92

2 টি মাত্রিক অ্যারে সমাধান

দয়া করে এটি চেষ্টা করুন:

$array  = your array

$result = call_user_func_array('array_merge', $array);

echo "<pre>";
print_r($result);

সম্পাদনা: 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


আপনাকে ধন্যবাদ, প্রথমটি এমন একটি অ্যারেতে কাজ করেছিল যা আমি পিডিও থেকে পেয়েছিলাম যেখানে অন্যান্য সমাধানগুলি পায় নি।
জাল

7
এটি একটি দুর্বল কৌশল। call_user_func_array('array_merge', [])(খালি অ্যারে লক্ষ করুন) নাল ফেরায় এবং পিএইচপি সতর্কতা ত্রুটি ট্রিগার করে। এটি একটি চটজলদি সমাধান যদি আপনি যদি জানেন যে আপনার অ্যারেটি খালি হবে না তবে এটি সাধারণ ধারণা নয় যা অনেকে করতে পারে।
ছাগল

ওপি বিশেষত পুনরাবৃত্তির সমাধানের জন্য বলেছে।
ইলেক্ট্রা

বাহ, শান্ত 2 ডি ফ্ল্যাটার! তবে বিজ্ঞপ্তিটি কেবল ব্যবহারের প্রতিরোধে$result = $array ?call_user_func_array('array_merge', $array) : [];
আলেকজান্ডার গনচরভ

শীতল ব্রুহ, তবে আপনার কি সুযোগ নেই একটি পাল্টা-ফাংশন অ্যারে-ডিফ্ল্যাটেন?
ফ্যান্টমএক্স 1

64

পিএইচপি 5.6 এবং উপরে আপনি অপারেটরের array_mergeসাথে বাইরের অ্যারে আনপ্যাক করার পরে দুটি মাত্রিক অ্যারে সমতল করতে পারেন ...। কোডটি সহজ এবং স্পষ্ট।

array_merge(...$a);

এটি সাহসী অ্যারে সংগ্রহের সাথেও কাজ করে।

$a = [[10, 20], [30, 40]];
$b = [["x" => "X", "y" => "Y"], ["p" => "P", "q" => "Q"]];

print_r(array_merge(...$a));
print_r(array_merge(...$b));

Array
(
    [0] => 10
    [1] => 20
    [2] => 30
    [3] => 40
)
Array
(
    [x] => X
    [y] => Y
    [p] => P
    [q] => Q
)

বাইরের অ্যারেতে সংখ্যাযুক্ত কী না থাকলে এটি কাজ করে না। সেক্ষেত্রে আপনাকে array_valuesপ্রথমে কল করতে হবে ।

$c = ["a" => ["x" => "X", "y" => "Y"], "b" => ["p" => "P", "q" => "Q"]];
print_r(array_merge(...array_values($c)));

Array
(
    [x] => X
    [y] => Y
    [p] => P
    [q] => Q
)

আপডেট: @ মোহাম্মদঘড়িবের মন্তব্যের ভিত্তিতে

বাইরের অ্যারে ফাঁকা থাকলে এটি ত্রুটি ছুঁড়ে array_mergeদেবে , যেহেতু শূন্য আর্গুমেন্টের সাথে ডাকা হবে। প্রথম যুক্তি হিসাবে খালি অ্যারে যুক্ত করে এড়ানো যায়।

array_merge([], ...$a);

1
এটি কেবলমাত্র কাজ করে যখন অ্যারের প্রতিটি উপাদান একটি অ্যারে হয়। অ্যারেতে যদি মিশ্রিত ধরণের যেমন স্কেলারগুলি থাকে তবে একটি ত্রুটি ঘটবে।
ওথিউস

@ অথিউস এটি কারণ যে উপরের সমাধানটি পুনরাবৃত্তি ব্যবহার করে না। যেমনটি আপনি বলেছেন, এটির জন্য একটি অ্যারের প্রয়োজন। তবে প্লাস দিকে, এটি অন্যান্য পদ্ধতিগুলির তুলনায় এটি আরও দ্রুত হওয়া উচিত, কারণ এতে ফাংশন কলগুলির অতিরিক্ত ওভারহেড নেই।
জয়স বাবু

2
বাইরের অ্যারে ফাঁকা থাকলে একটি ত্রুটি ফেলবে, খালি অ্যারের সাথে একত্রিত হলে এড়াতে পারা যায়array_merge([], ...$a);
মোহাম্মদ গারিব

পছন্দ করেছেন
জয়েস বাবু


24

ডাব্লু / ও পুনরাবৃত্তি সমতল করতে (যেমন আপনি বলেছেন), আপনি একটি স্ট্যাক ব্যবহার করতে পারেন । স্বাভাবিকভাবেই আপনি এটিকে নিজের মতো করে ফাংশনে রাখতে পারেন 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
        {
            $stack = array_merge(array_values($value), $stack);
        }
        else // a value to take
        {
           $flat[] = $value;
        }
    }
    return $flat;
}

উপাদানগুলি তাদের ক্রমে প্রক্রিয়া করা হয়। যেহেতু সাবলিমেন্টগুলি স্ট্যাকের শীর্ষে স্থানান্তরিত হবে, সেগুলি পরে প্রক্রিয়া করা হবে।

কীগুলিও আমলে নেওয়া সম্ভব, তবে, স্ট্যাকটি পরিচালনা করার জন্য আপনার আলাদা কৌশল দরকার need এটি প্রয়োজন কারণ আপনাকে সাব-অ্যারেতে সম্ভাব্য নকল কীগুলি মোকাবেলা করতে হবে। সম্পর্কিত প্রশ্নের একই উত্তর: পিএইচপি কী সংরক্ষণের সময় বহুমাত্রিক অ্যারে দিয়ে যান

আমি বিশেষভাবে নিশ্চিত নই, তবে দ্বিতীয়টি অতীতে এটি পরীক্ষা করেছিল: RecurisiveIteratorএটি পুনরাবৃত্তি ব্যবহার করে, তাই এটি আপনার কী প্রয়োজন তা নির্ভর করে। পাশাপাশি স্ট্যাকের উপর ভিত্তি করে একটি পুনরাবৃত্ত পুনরুক্তি তৈরি করা সম্ভব হওয়া উচিত:

foreach(new FlatRecursiveArrayIterator($array) as $key => $value)
{
    echo "** ($key) $value\n";
}

ডেমো

আমি এখন পর্যন্ত এটি তৈরি করিনি, RecursiveIteratorযার ভিত্তিতে আমার মনে হয় এটি একটি দুর্দান্ত ধারণা based


অসামান্য অ্যারে_ফ্লেটেন ফাংশনের জন্য +1। আমি যোগ করতে ছিল if(!empty($value)){$flat[] = $value}আর বিবৃতি ভিতরে খালি হচ্ছে বিন্যাসের ফলাফল যোগ করা প্রতিরোধ। দুর্দান্ত কাজ!
অ্যালেক্স সার্নোস্কি

19

সোজা এবং ওয়ান-লাইনারের উত্তর।

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

আউটপুট (PsySH এ):

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

সভিশের উত্তর উদ্ধৃত :

শুধু দ্বিতীয় প্যারামিটারটি মিথ্যা যোগ ($use_keys)করার iterator_to_array কল


কেবল পরিষ্কার করার জন্য, এটি কীগুলি (এমনকি সংখ্যাসূচকগুলিও) সংরক্ষণ করে যাতে একই কী রয়েছে এমন মানগুলি হারিয়ে যায়। উদাহরণস্বরূপ $array = ['a',['b','c']]হয়ে যায় Array ([0] => b, [1] => c )'a'হারিয়ে কারণ 'b'এছাড়াও একটি মূল আছে 0
নাইজেল অ্যাল্ডারটন

1
@ নিগেল্ডার্টন কেবলমাত্র falseদ্বিতীয় পরামিতি ( $use_keys) হিসাবে যুক্ত করুন iterator_to_array
সুইভিশ

18

পুনরাবৃত্তি ব্যবহার করে। আশা করা যায় যে এটি কতটা জটিল নয়, আপনার পুনরাবৃত্তির ভয়টি কখনই জটিল নয় তা দেখলেই তা কেটে যাবে।

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>

1
আমি পুনরাবৃত্তি ভয় করি না, আমি এটি করার অন্যান্য উপায়গুলিও শিখতে চাই।
অ্যালিক্স অ্যাক্সেল

13
এই পুনরাবৃত্তির জন্য +1: আশা করা যায় যে এটি কতটা জটিল নয়, আপনার পুনরাবৃত্তির ভয়টি কখনই জটিল নয় তা একবার নষ্ট হয়ে যাবে।
টিবেরিউ-আয়নু স্টান

1
ঠিক আছে, এটা আমার শেষ। কীভাবে এটি সম্ভব, এই জবাব ("আমি পুনরাবৃত্তি ভয় করি না") প্রাথমিক বিবৃতি ("(...) এর চেয়ে সাড়ে তিন বছরের বড় (" (...) আপনার পুনরাবৃত্তির ভয়টি কেটে যাবে (... ) "), 5 ফেব্রুয়ারী '13 এ তৈরি?
ট্রেজার্ড

18

কেবল ভেবেছি আমি এটি চিহ্নিত করতে পারি যে এটি একটি ভাঁজ, তাই অ্যারে_ড্রেস ব্যবহার করা যেতে পারে:

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

অবশ্যই, আমরা লুপগুলিও ব্যবহার করতে পারি তবে প্রশ্নটি অ্যারে_ম্যাপ বা অ্যারে_ভ্যালুগুলির লাইন বরাবর একটি সংযুক্তকারী ফাংশন জানতে চায়।


বহুমাত্রিক! = দ্বি-মাত্রিক।
অ্যালিক্স অ্যাক্সেল

@atamur এটি পিএইচপি 5.3+ এ কাজ করে। অ্যারে_ড্রেস এর চেঞ্জলগে যেমন উল্লেখ করা হয়েছে, $ প্রাথমিক কেবল 5.3 এর পূর্বে একটি পূর্ণসংখ্যা হতে পারে, তারপরে এটি "মিশ্র" (যেমন আপনার হ্রাস ফাংশনটি সমর্থন করে এমন কিছু) হতে দেওয়া হয়েছিল
ওয়ারবো

1
@ অ্যালেক্সএক্সেল আপনি ঠিক যে বহুমাত্রিক! = দ্বি-মাত্রিক, তবে এটি যে কোনও স্তরের সমতলকরণের জন্য রচনা করা যেতে পারে। ভাঁজ রচনা করার একটি দুর্দান্ত পরিণতি হ'ল এটি একটি নির্দিষ্ট সীমা মেনে চলে; যদি আমার কাছে অ্যারেটি 5 টি স্তরে নেস্টেড থাকে তবে আমি foldএটি 4 টি স্তরে বা fold . foldএটি 3 স্তর fold . fold . foldপেতে পারি বা এটি 2 স্তরের পেতে পারি etc. ইত্যাদি এটি বাগগুলি আড়াল হতে বাধা দেয়; যেমন। যদি আমি 5 ডি অ্যারে সমতল করতে চাই তবে আমাকে একটি 4 ডি অ্যারে দেওয়া হয় তবে ত্রুটি তত্ক্ষণাত্ ট্রিগার হয়ে যাবে।
ওয়ারবো

আমি 2-মাত্রিক অ্যারেগুলির জন্য এই সমাধানটি পছন্দ করি। পুরোপুরি বিল ফিট করে।
টম

আমি একমত যে আপনার একক স্তরের সংজ্ঞাটি সর্বোত্তম উত্তর, এটি আশ্চর্যরকম ঝরঝরে। তবে আমি মনে করি আপনি এটির ভুল নাম দিয়েছেন $concat, আমার মনে হয় আপনার কেবল এটি কল করা উচিত $flattenarray_mergeকনক্যাট এর পিএইচপি সমতুল্য। আমিarray_concat একটি উপনাম হিসাবে যুক্ত করার চেষ্টা করেছিarray_merge
icc97

9

কেবলমাত্র দ্বিমাত্রিক অ্যারে ফ্ল্যাট করে:

$arr = [1, 2, [3, 4]];
$arr = array_reduce($arr, function ($a, $b) {
     return array_merge($a, (array) $b);
}, []);

// Result: [1, 2, 3, 4]

5

এই সমাধানটি পুনরাবৃত্তিযোগ্য নয়। নোট করুন যে উপাদানগুলির ক্রমটি কিছুটা মিশ্রিত হবে।

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

1
চতুর ধারণা, কিন্তু একটি বাগ আছে। "$ অ্যারে [] = $ মান" $ মানের সমস্ত উপাদানকে $ অ্যারেতে যোগ করে না , এটি কেবল $ মানকে নিজের করে দেয়। আপনি যদি এই কোডটি চালনা করেন তবে তা অনির্দিষ্টকালের জন্য লুপ হয়ে যাবে।
টড ওভেন

হ্যাঁ, shiftingঅ্যারের মানটি বন্ধ করে দেওয়া এবং এটি আবার শেষ করে দেওয়া খুব বেশি অর্থবোধ করে না। আমার ধারণা আপনি array_merge()পরিবর্তে চেয়েছিলেন ?
প্রতারণা করুন

4

আমি বিশ্বাস করি কোনও মিউটেশন বা অপরিচিত শ্রেণি ব্যবহার না করেই এটিই সবচেয়ে পরিষ্কার সমাধান।

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

3

নিম্নলিখিত সহজ ফাংশন চেষ্টা করুন:

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',
)

সম্ভবত আপনার ফাংশনটি পরীক্ষা করা উচিত ... প্রত্যাশার মতো কোনও কাজ মনে হচ্ছে না
এমিলিয়ানো

@ এমিলিয়ানো একটি নতুন প্রশ্ন জিজ্ঞাসা করার চেষ্টা করুন, সম্ভবত আপনার ইনপুট ডেটা আলাদা, তাই এটি আপনার বিশেষ ক্ষেত্রে কার্যকর হবে না।
কেনারব

আমাদের কয়েকটি সমস্যা রয়েছে যার একটি হ'ল ফাংশন, আপনি সেই পয়েন্টটি উন্নত করতে পারবেন যে আপনি এখানে নতুন লোক ছিলেন না, আপনার কোডটি পিএইচপি-র একটি নির্দিষ্ট সংস্করণ দিয়ে কাজ করে তবে এটি তৃতীয় বলে যদি সমস্ত তথ্য দিয়ে কাজ না করে তবে এটি জানা উচিত you
এমিলিয়ানো

2

কৌশলটি উত্স এবং গন্তব্য অ্যারে উভয়ই রেফারেন্সের মাধ্যমে পাস করছে।

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

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

গিস্ট স্নিপেট


এটি কেবল দ্বি-মাত্রিক অ্যারে সমর্থন করে বলে মনে হচ্ছে।
অ্যালিক্স অ্যাক্সেল

তুমি ঠিক. এটি ব্যবহার করার কোনও মানে নেই। আমি মনে করি সেরা সমাধানটি "অত্যধিক পিএইচপি" এর উত্তর।
আরশাম


2

আপনি যদি সত্যিই পুনরাবৃত্তি পছন্দ না করেন ... পরিবর্তে স্থানান্তরিত করার চেষ্টা করুন :)

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

দ্রষ্টব্য: এই সাধারণ সংস্করণে এটি অ্যারে কীগুলি সমর্থন করে না।


এটি একটি আকর্ষণীয় পদ্ধতির। অন্যান্য সমাধানগুলির বিপরীতে, এটি মূল অ্যারে ($ এ) সম্পাদনা করে। আপনি যদি এটির সাথে প্রতিস্থাপন করেন তবে এটি continueকিছুটা দ্রুত।
pcarvalho

2

পুনরাবৃত্ত জেনারেটর ব্যবহার সম্পর্কে কীভাবে? 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;
        }
    }
}

1

পিএইচপি 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;
}

এই কোড-শুধুমাত্র উত্তরের সাথে দয়া করে কিছু ব্যাখ্যা অন্তর্ভুক্ত করুন।
মিকম্যাকুসা

1

এই সংস্করণটি গভীর, অগভীর বা একটি নির্দিষ্ট সংখ্যার স্তর করতে পারে:

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

এই স্নিপেট কী করতে পারে তা ব্যাখ্যা করার বাইরে, ভবিষ্যতে গবেষকরা কীভাবে এটি কাজ করে তা ব্যাখ্যা করুন।
মিকম্যাকুসা

1

কারণ কোড এখানে ভীতিকর দেখায়। এখানে এমন একটি ফাংশন রয়েছে যা একটি বহুমাত্রিক অ্যারেটিকে এইচটিএমএল ফর্মের সাথে সামঞ্জস্যপূর্ণ সিনট্যাক্সে রূপান্তরিত করবে তবে এটি পড়া সহজ।

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

1

এটি ব্যবহার করে অর্জন করা যেতে পারে 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


0

এটি আমার সমাধান, একটি রেফারেন্স ব্যবহার করে:

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

আপনার স্নিপেট কীভাবে কাজ করে এবং কেন এটি একটি ভাল ধারণা সে সম্পর্কে কিছু ব্যাখ্যা অন্তর্ভুক্ত করুন। কোড-কেবলমাত্র উত্তরগুলি স্ট্যাকওভারফ্লোতে স্বল্প-মূল্যবান কারণ তারা ওপি এবং ভবিষ্যতের গবেষকদের শিক্ষিত / ক্ষমতায়নের একটি দুর্বল কাজ করে। মনে রাখবেন, আমরা কখনই কেবল ওপি-তে কথা বলি না; পুরানো পৃষ্ঠাগুলি নতুন পৃষ্ঠাগুলি বন্ধ করতে ব্যবহৃত হয়, তাই ভবিষ্যতের প্রশ্নকারীদের জন্য সমস্যাগুলি সমাধান করার জন্য পৃষ্ঠাগুলি যথেষ্ট তথ্যযুক্ত হওয়া দরকার।
মিকম্যাকুসা

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

0

এখানে একটি সরল পদ্ধতি রয়েছে:

$My_Array = array(1,2,array(3,4, array(5,6,7), 8), 9);

function checkArray($value) {
    foreach ($value as $var) {
        if ( is_array($var) ) {
            checkArray($var);
        } else {
            echo $var;
        }
    }
}

checkArray($My_Array);

0

যে কেউ এর সত্যই পরিষ্কার সমাধান খুঁজছেন; এখানে একটি বিকল্প রয়েছে:

$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

0

কেবল অন্য কোনও সমাধান পোস্ট করা)

function flatMultidimensionalArray(array &$_arr): array
{
    $result = [];
    \array_walk_recursive($_arr, static function (&$value, &$key) use (&$result) {
        $result[$key] = $value;
    });

    return $result;
}

0

আপনি যদি আপনার কীগুলি রাখতে চান তবে এটি সমাধান।

function reduce(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
)

-1

আমার এইচটিএমএল ইনপুট ফর্ম্যাটে পিএইচপি বহুমাত্রিক অ্যারে উপস্থাপন করা প্রয়োজন।

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


@ অ্যালেক্সএক্সেল এই মন্তব্যটি কীভাবে আপেক্ষিক? ভুল পোস্ট ..?
গাজুস

না। আমি ভেবেছিলাম এটি আপনি যা করছেন তার সাথে এটি বেশ মিল ছিল এবং এটি ভাগ করে নেওয়ার সিদ্ধান্ত নিয়েছে, আমি মনে করি কেবলমাত্র পার্থক্যটি হ'ল আমার প্রতিনিধিত্বটি বৈধ পিএইচপি - ফর্মের ক্ষেত্রেও বৈধ $var['a']['b']['c'][0] = 'a'; ...
অ্যালিক্স অ্যাক্সেল

আমি ইচ্ছাকৃতভাবে এইচটিএমএল আউটপুট প্রয়োজন। যদিও ভাগ করে নেওয়ার জন্য আপনাকে ধন্যবাদ।
গাজুস

1
আমি অনুভব করি যে এটি ভুল প্রশ্নের সঠিক উত্তর। উত্তর দেওয়ার সময়, দয়া করে প্রশ্নের উত্তর দেওয়ার চেষ্টা করুন - অন্যথায় পৃষ্ঠাগুলি মূল সমস্যা থেকে সরে যেতে পারে এবং ভবিষ্যতের গবেষকদের বিভ্রান্ত করতে পারে।
মিকম্যাকুসা

-1

যদি আপনার কাছে অবজেক্টগুলির একটি অ্যারে থাকে এবং নোড দিয়ে এটি সমতল করতে চান তবে কেবল এই ফাংশনটি ব্যবহার করুন:

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;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.