1

I need to dynamically extract only certain keys from an array.

Ex:

$array = [
        "a" => true,
        "b" => false,
        "c" => [
            0 => [
                "a" => "x",
                "b" => [
                    "x" => "Y"
                ]
            ],
            1 => [
                "a" => "x",
                "b" => [
                    "x" => "Y"
                ]
            ],
        ]
    ];

And from it I need to extract the following array, which can change:

$newArray = [
        "b" => false,
        "c" => [
            0 => [
                "b" => [
                    "x" => "Y"
                ]
            ],
            1 => [
                "b" => [
                    "x" => "Y"
                ]
            ],
        ]
    ];
Al Foиce ѫ
  • 4,195
  • 12
  • 39
  • 49
  • So you want values that are NOT `true` or what? Why do you want `b` and `c` but not `a`? What is the logic / rule? – AbraCadaver Oct 18 '19 at 20:39
  • I need to generate a report from a json data, where the user define the report fields, then I need to get only same values from json, – Conrado Lemos Oct 18 '19 at 20:45
  • 1
    Still not clear, `a` is `true` but you get `b` keys from the `c` array. You won't get a good answer without explaining HOW and WHY. – AbraCadaver Oct 18 '19 at 22:50

2 Answers2

0

this might by easy with the following recursive function:

<?php
$array = [
            "a" => true,
            "b" => false,
            "c" => [
                0 => [
                    "a" => "x",
                    "b" => [
                        "x" => "Y"
                    ]
                ],
                1 => [
                    "a" => "x",
                    "b" => [
                        "x" => "Y"
                    ]
                ],
            ]
        ];

$cleaned_array = unset_by_key($array,"a");    
$extracted_array = arrayRecursiveDiff ($array, $cleaned_array);

print_r($cleaned_array);  
print_r($extracted_array);

function unset_by_key ($arr,$nkey) {
  unset($arr[$nkey]);
  foreach ($arr as $key=>$val) {
    if (is_array($val)) {
        $arr[$key] = unset_by_key($val,$nkey);
    }
  }
  return $arr;
}

// THX TO: https://stackoverflow.com/questions/3876435/recursive-array-diff
function arrayRecursiveDiff($aArray1, $aArray2) {
  $aReturn = array();

  foreach ($aArray1 as $mKey => $mValue) {
    if (array_key_exists($mKey, $aArray2)) {
      if (is_array($mValue)) {
        $aRecursiveDiff = arrayRecursiveDiff($mValue, $aArray2[$mKey]);
        if (count($aRecursiveDiff)) { $aReturn[$mKey] = $aRecursiveDiff; }
      } else {
        if ($mValue != $aArray2[$mKey]) {
          $aReturn[$mKey] = $mValue;
        }
      }
    } else {
      $aReturn[$mKey] = $mValue;
    }
  }
  return $aReturn;
} 

?>
MatWer
  • 136
  • 6
0

No need for recursive functions, you can just use array_intersect_key if you only intend to select by keys first level deep:

$arr = [
    'a' => true,
    'b' => false,
    'c' => [
        [
            'a' => 'x',
            'b' => [
                'x' => 'Y'
            ]
        ],
        [
            'a' => 'x',
            'b' => [
                'x' => 'Y'
            ]
        ],
    ]
];
function getKeys(array $arr, array $keys) {
    return array_intersect_key($arr, array_fill_keys($keys, null));
}

$result = getKeys($arr, ['b', 'c']);
print_r($result);

Hope that helps,

Miroslav Glamuzina
  • 4,472
  • 2
  • 19
  • 33