如何将数组缩小为多个小数组?

I have this array:

$arr = [{"From"=>"Jack", "To"=>"Peter"},
        {"From"=>"Jack", "To"=>"John"},
        {"From"=>"Jack", "To"=>"Ali"},
        {"From"=>"Ali", "To"=>"Jack"},
        {"From"=>"Ali", "To"=>"Martin"},
        {"From"=>"Jack", "To"=>"Barmar"},
        {"From"=>"Peter", "To"=>"John"}];

Now I need to make multiple array based on From key. I mean, I need to separate them. Something like this:

$arr1 = [{"From"=>"Jack", "To"=>"Peter"},
         {"From"=>"Jack", "To"=>"John"},
         {"From"=>"Jack", "To"=>"Ali"},
         {"From"=>"Jack", "To"=>"Barmar"}];

$arr2 = [{"From"=>"Ali", "To"=>"Jack"},
         {"From"=>"Ali", "To"=>"Martin"}];

$arr3 = [{"From"=>"Peter", "To"=>"John"}];

Has someone any idea how should I do that?

You have to create a new array by some simple implementation of your own logic. Take a look at this simple demonstration:

<?php
$input = [
    ["From"=>"Jack", "To"=>"Peter"],
    ["From"=>"Jack", "To"=>"John"],
    ["From"=>"Jack", "To"=>"Ali"],
    ["From"=>"Ali", "To"=>"Jack"],
    ["From"=>"Ali", "To"=>"Martin"],
    ["From"=>"Jack", "To"=>"Barmar"],
    ["From"=>"Peter", "To"=>"John"]
];
$output = [];

array_walk($input, function($element) use (&$output) {
    $output[$element['From']][] = $element;
});

print_r(array_values($output));

The output of above obviously is:

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [From] => Jack
                    [To] => Peter
                )

            [1] => Array
                (
                    [From] => Jack
                    [To] => John
                )

            [2] => Array
                (
                    [From] => Jack
                    [To] => Ali
                )

            [3] => Array
                (
                    [From] => Jack
                    [To] => Barmar
                )

        )

    [1] => Array
        (
            [0] => Array
                (
                    [From] => Ali
                    [To] => Jack
                )

            [1] => Array
                (
                    [From] => Ali
                    [To] => Martin
                )

        )

    [2] => Array
        (
            [0] => Array
                (
                    [From] => Peter
                    [To] => John
                )

        )

)

The braces in your notation should be square brackets. Here is what you could do:

$arr = [["From"=>"Jack", "To"=>"Peter"],
        ["From"=>"Jack", "To"=>"John"],
        ["From"=>"Jack", "To"=>"Ali"],
        ["From"=>"Ali", "To"=>"Jack"],
        ["From"=>"Ali", "To"=>"Martin"],
        ["From"=>"Jack", "To"=>"Barmar"],
        ["From"=>"Peter", "To"=>"John"]];

$res = [];
foreach ($arr as $row) {
    if (!isset($res[$row['From']])) $res[$row['From']] = [];
    $res[$row['From']][] = $row['To'];
}

print_r($res);

$res will contain:

[
    "Jack" => ["Peter", "John", "Ali", "Barmar"],
    "Ali" => ["Jack", "Martin"],
    "Peter" => ["John"]
]

See it on eval.in

Simple iteration of the array and storing the elements to result array by From key solves your needs:

$arr = [["From"=>"Jack", "To"=>"Peter"],
        ["From"=>"Jack", "To"=>"John"],
        ["From"=>"Jack", "To"=>"Ali"],
        ["From"=>"Ali", "To"=>"Jack"],
        ["From"=>"Ali", "To"=>"Martin"],
        ["From"=>"Jack", "To"=>"Barmar"],
        ["From"=>"Peter", "To"=>"John"]];

$result = array();
foreach ($arr as $item) {
   $result[$item['From']][] = $item;
}

The result:

array (size=3)
  'Jack' => 
    array (size=4)
      0 => 
        array (size=2)
          'From' => string 'Jack' (length=4)
          'To' => string 'Peter' (length=5)
      1 => 
        array (size=2)
          'From' => string 'Jack' (length=4)
          'To' => string 'John' (length=4)
      2 => 
        array (size=2)
          'From' => string 'Jack' (length=4)
          'To' => string 'Ali' (length=3)
      3 => 
        array (size=2)
          'From' => string 'Jack' (length=4)
          'To' => string 'Barmar' (length=6)
  'Ali' => 
    array (size=2)
      0 => 
        array (size=2)
          'From' => string 'Ali' (length=3)
          'To' => string 'Jack' (length=4)
      1 => 
        array (size=2)
          'From' => string 'Ali' (length=3)
          'To' => string 'Martin' (length=6)
  'Peter' => 
    array (size=1)
      0 => 
        array (size=2)
          'From' => string 'Peter' (length=5)
          'To' => string 'John' (length=4)

use array_push() to push values into new array.

Here is the exact output you may want,

<?php
$arr = [
    ["From" => "Jack", "To" => "Peter"],
    ["From" => "Jack", "To" => "John"],
    ["From" => "Jack", "To" => "Ali"],
    ["From" => "Ali", "To" => "Jack"],
    ["From" => "Ali", "To" => "Martin"],
    ["From" => "Jack", "To" => "Barmar"],
    ["From" => "Peter", "To" => "John"],
];
$from = '';
$temp = [];
function array_orderby()
{
    $args = func_get_args();
    $data = array_shift($args);
    foreach ($args as $n => $field) {
        if (is_string($field)) {
            $tmp = array();
            foreach ($data as $key => $row) {
                $tmp[$key] = $row[$field];
            }

            $args[$n] = $tmp;
        }
    }
    $args[] = &$data;
    call_user_func_array('array_multisort', $args);
    return array_pop($args);
}
function custom_function($arr)
{
    $arr = array_orderby($arr, 'From', SORT_ASC);
    foreach ($arr as $k => $v) {
        if (empty($from) || $from != $v['From']) {
            if (empty($from)) {
                $i = 1;
            } else {
                $i++;
            }
            $from = $v['From'];
        }
        $temp['arr' . $i][] = $v;
    }
    return $temp;
}
$result = custom_function($arr);

extract($result);
print_r($arr1);
print_r($arr2);
print_r($arr3);

Working link

Give it a try.

Hope this helps,

$arr = [["From"=>"Jack", "To"=>"Peter"],
        ["From"=>"Jack", "To"=>"John"],
        ["From"=>"Jack", "To"=>"Ali"],
        ["From"=>"Ali", "To"=>"Jack"],
        ["From"=>"Ali", "To"=>"Martin"],
        ["From"=>"Jack", "To"=>"Barmar"],
        ["From"=>"Peter", "To"=>"John"]
    ];

function getFrom($from, $arr) {
    return array_filter($arr, function($k) use ($from){
        return $k["From"] == $from;
    });
}

$fromArray = getFrom('Jack', $arr);