Как изменить формат массива? [Дубликат]

Эта страница сообщает вам все, что вам нужно знать о сортировке коллекций, таких как ArrayList.

В основном вам нужно

  • сделать свой Contact реализует интерфейс Comparable, создавая в нем метод public int compareTo(Contact anotherContact).
  • Как только вы сделаете это, вы можете просто вызвать Collections.sort(myContactList);, где myContactList - ArrayList (или любой другой набор из Contact).

Также существует и другой способ создания класса компаратора, и вы также можете прочитать об этом со связанной страницы.

Пример:

public class Contact implements Comparable {

    ....

    //return -1 for less than, 0 for equals, and 1 for more than
    public compareTo(Contact anotherContact) {
        int result = 0;
        result = getName().compareTo(anotherContact.getName());
        if (result != 0)
        {
            return result;
        }
        result = getNunmber().compareTo(anotherContact.getNumber());
        if (result != 0)
        {
            return result;
        }
        ...
    }
}

190
задан BoltClock 8 January 2012 в 21:41
поделиться

23 ответа

Вы можете использовать стандартную библиотеку PHP (SPL) для «скрытия» рекурсии.

$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 
218
ответ дан VolkerK 26 August 2018 в 02:07
поделиться

Если у вас есть массив объектов и вы хотите сгладить его с помощью узла, просто используйте эту функцию:

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;
}
-1
ответ дан A.L 26 August 2018 в 02:07
поделиться

Для 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;
}
1
ответ дан Alexei T 26 August 2018 в 02:07
поделиться
/**
 * 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));
    }
);

Фрагмент gist

2
ответ дан Arsham 26 August 2018 в 02:07
поделиться

Сглаживает только двухмерные массивы:

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

// Result: [1, 2, 3, 4]
4
ответ дан artnikpro 26 August 2018 в 02:07
поделиться

Использует рекурсию.

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>

Выход:

<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>
16
ответ дан BoltClock 26 August 2018 в 02:07
поделиться

Если вам действительно не нравится рекурсия ... try shifting вместо: :)

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

Примечание: в этой простой версии это не поддерживает ключи массива.

2
ответ дан BurninLeo 26 August 2018 в 02:07
поделиться

Потому что код в здесь выглядит пугающе. Вот функция, которая также преобразует многомерный массив в синтаксис, совместимый с форматом 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;
}
23
ответ дан Community 26 August 2018 в 02:07
поделиться

Я считаю, что это самое чистое решение без использования каких-либо мутаций или незнакомых классов.

<?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
ответ дан Dariush Alipour 26 August 2018 в 02:07
поделиться
<?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
ответ дан Furqan Freed 26 August 2018 в 02:07
поделиться

Мне нужно было представить многомерный массив PHP в формате ввода HTML.

$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"
}
-1
ответ дан Gajus 26 August 2018 в 02:07
поделиться

Вы можете сделать это с помощью ouzo goodies :

 $result = Arrays::flatten($multidimensional);

Смотрите: Здесь

2
ответ дан heena Jethva 26 August 2018 в 02:07
поделиться

Вот упрощенный подход:

$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
ответ дан Jack Nicholson 26 August 2018 в 02:07
поделиться

Возможно ли, в PHP, сгладить (bi / multi) мерный массив без использования рекурсии или ссылок?

Как и в PHP 7, я не знаю, что , Я создал решение, которое я называю array_moonwalk , которое использует как ссылки, так и рекурсию для сглаживания и дедупликации многомерного массива и сохраняет глубину самого глубокого узла для каждого дубликата, найденного для многомерной реконструкции массива.

Управляет дедупликацией листовых узлов на разных глубинах без , используя foreach, и единственный ответ до сих пор, чтобы использовать array_walk. Не проверен на производительность. YMMV.

-1
ответ дан Josh Habdas 26 August 2018 в 02:07
поделиться

В PHP 5.6 и выше вы можете сгладить двухмерные массивы с помощью array_merge после распаковки внешнего массива с помощью оператора .... Код прост и понятен.

$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
)
8
ответ дан Joyce Babu 26 August 2018 в 02:07
поделиться

Попробуйте следующую простую функцию:

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',
)
3
ответ дан kenorb 26 August 2018 в 02:07
поделиться

Решение для 2-мерного массива

Попробуйте следующее:

$array  = your array

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

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

EDIT: 21-Aug-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

61
ответ дан M1K1O 26 August 2018 в 02:07
поделиться

Это мое решение, используя ссылку:

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
ответ дан Martyn Shutt 26 August 2018 в 02:07
поделиться

Трюк передает исходный и целевой массивы по ссылке.

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
ответ дан Rick Garcia 26 August 2018 в 02:07
поделиться

Эта версия может делать глубокое, неглубокое или определенное количество уровней:

/**
 * @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
ответ дан ryanve 26 August 2018 в 02:07
поделиться

Ах, без рекурсии !!! даже карта, уменьшить, фильтр включает рекурсию. Это невозможно, если вы не используете некоторые хакские php-пути, как показано ниже. Серьезно, ни один цикл не задействован в коде ниже, извините, если он убил хорошие функции массива :):)

$arr=array(1,2,array(3,4, array(5,6,7), 8), 9);
$json=json_encode($arr);
$hacked_json=str_replace(['[',']'],"",$json);
$hacked_array=json_decode('['.$hacked_json.']');
echo "<pre>";
print_r($hacked_array);

output

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 1
    [5] => 2
    [6] => 6
    [7] => 7
    [8] => 8
    [9] => 9
)

работает для пары вложенных ключевых значений как скважина

$arr=array(1,2,array(3,4, array(array("s"=>array(1),"w"=>array('q'=>1,'v'=>12)),6,7), 8), 9);
echo "<pre>";
print_r($arr);
$json=json_encode($arr);
$hacked_json=str_replace(['[',']'],"",$json);
$hacked_array=json_decode('['.$hacked_json.']');
echo "<pre>";
print_r(json_decode(json_encode($hacked_array), True));

выход

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => Array
        (
            [s] => 1
            [w] => Array
                (
                    [q] => 1
                    [v] => 12
                )

        )

    [5] => 6
    [6] => 7
    [7] => 8
    [8] => 9
)
1
ответ дан sumit 26 August 2018 в 02:07
поделиться

Это решение является нерекурсивным. Обратите внимание, что порядок элементов будет несколько смешанным.

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;
}
241
ответ дан too much php 26 August 2018 в 02:07
поделиться

Просто подумал, что я бы сказал, что это сгиб, поэтому можно использовать array_reduce:

array_reduce($my_array, 'array_merge', array());

EDIT: Обратите внимание, что это может быть составлено для сглаживания любого количества уровней. Мы можем сделать это несколькими способами:

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

14
ответ дан Warbo 26 August 2018 в 02:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: