Самый простой способ удалить ключи из 2D-массива? - PullRequest
6 голосов
/ 06 апреля 2010

У меня есть массив, который выглядит так:

array(
  0 => array(
    'key1' => 'a',
    'key2' => 'b',
    'key3' => 'c'
  ),
  1 => array(
    'key1' => 'c',
    'key2' => 'b',
    'key3' => 'a'
  ),
  ...
)

Мне нужна функция для получения массива, содержащего только (переменное) количество ключей, то есть redu_array (array ('key1', 'key3')); должен вернуть:

array(
  0 => array(
    'key1' => 'a',
    'key3' => 'c'
  ),
  1 => array(
    'key1' => 'c',
    'key3' => 'a'
  ),
  ...
)

Какой самый простой способ сделать это? Если возможно, без каких-либо дополнительных вспомогательных функций, таких как array_filter или array_map, так как мои коллеги уже жалуются на то, что я использую слишком много функций.

Исходный массив всегда будет иметь заданные ключи, поэтому проверка наличия не требуется.

Бонусные баллы, если значения уникальны (ключи всегда будут связаны друг с другом, что означает, что если ключ1 имеет значение a, то другой ключ (ключи) всегда будет иметь значение b).

Мое текущее решение, которое работает, но довольно неуклюже (даже название ужасное, но не может найти лучшего):

function get_unique_values_from_array_by_keys(array $array, array $keys)
{
        $result = array();
        $found = array();

        if (count($keys) > 0)
        {
                foreach ($array as $item)
                {
                        if (in_array($item[$keys[0]], $found)) continue;
                        array_push($found, $item[$keys[0]]);
                        $result_item = array();
                        foreach ($keys as $key)
                        {
                                $result_item[$key] = $item[$key];
                        }
                        array_push($result, $result_item);
                }
        }
        return $result;
}

Добавление
Версия PHP 5.1.6.

Ответы [ 2 ]

6 голосов
/ 06 апреля 2010

Если вашим коллегам не нравятся array_filter или array_map, это их недостаток образования и вкуса. Хотя я не советую сжигать мосты на работе, они часто являются лучшим способом решения проблемы.

function reduce_array($array, $keys) {
  $keys_map = array_fill_keys($keys, true);
  return array_map(function ($subarray) use ($keys) {
    return array_intersect_key($subarray, $keys_map);
  }, $array);
}

(Примечание: анонимные функции, которые я использую выше, доступны только в PHP> = 5.3, поэтому вы, вероятно, не сможете их использовать)

Если вы должны сделать это без array_map и анонимных функций:

function reduce_array($array, $keys) {
  $ret = array();
  $keys_map = array_fill_keys($keys, true);
  foreach ($array as $subarray) {
    array_push($ret, array_intersect_key($subarray, $keys_map));
  }
  return $ret;
}

Чтобы кратко объяснить: во-первых, я использую array_fill_keys, чтобы превратить ключи из массива с целочисленной индексацией в массив с индексированной строкой (значение, которое я ему даю, true, здесь на самом деле не имеет значения). Это делает его подходящим входом для array_intersect_key, который будет делать именно то сокращение, которое вы ищете.

1 голос
/ 06 апреля 2010

Только с использованием функции in_array (). Количество символов можно уменьшить, но мы оставим его читабельным:

function reduce_array($array, $keys) {
    $res=array(); // Our result array
    foreach($array as $v1){ // Loop thru original array
        $t1=array(); // Our new inner array
        foreach($v1 as $k2=>$v2){ // Loop thru original inner array
            if(in_array($k2,$keys)) $t1[$k2]=$v2; //If inside inner array store
        }
        $res[]=$t1; //Add to result array
    }
    return($res);
}

Мне не терпится избавиться и от функции in_array (), но я действительно должен сделать некоторую работу;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...