Sampath Wijesinghe
Sampath Wijesinghe

Reputation: 690

Group associative array data by key prefix

I have a array like this

Array (
    [operator_15] => 3
    [fiter_15] => 4
    [operator_17] => 5
    [fiter_17] => 5
    [operator_19] => 4
    [fiter_19] => 2
)

I want to separate this array in to 2 arrays:

  1. key starting from fiter_
  2. key starting from operator_

I used array filter and it doesn't work. any other option?

$array = array_filter(
    $fitered_values,
    function($key) {
        return strpos($key, 'fiter_') === 0;
    }
);

Upvotes: 1

Views: 370

Answers (4)

mickmackusa
mickmackusa

Reputation: 48000

While iterating your array, populate a new array with first level (grouping) keys based on the prefix (substring before the underscore), then push the original associative data into that group.

Code: (Demo)

$result = [];
foreach ($array as $k => $v) {
    $result[strtok($k, '_')][$k] = $v;
}
var_export($result);

It is suboptimal programming to declare individual variables because this removes the convenience of being able to easily iterate related data (related by structure).

The above snippet will allow you to iterate $result and access all data sets or you can individually access a particular subset like $result['fiter'].

Upvotes: 1

Andreas
Andreas

Reputation: 23968

Just loop the array and substring what is before the _ with strpos and substr then you can filter them to a new array as this.
This method will also work with new array keys, see example:

$arr = array ( "operator_15" => 3, 
               "fiter_15" => 4, 
               "operator_17" => 5, 
               "fiter_17" => 5, 
               "somethingelse_12" => 99 // <--- Notice this line.
              );

foreach($arr as $key => $val){
    $subarr = substr($key,0, strpos($key, "_"));
    $new[$subarr][$key] = $val;
}

var_dump($new);

output:

array(3) {
["operator"]=>
  array(2) {
    ["operator_15"]=>
    int(3)
    ["operator_17"]=>
    int(5)
  }
  ["fiter"]=>
  array(2) {
    ["fiter_15"]=>
    int(4)
    ["fiter_17"]=>
    int(5)
  }
  ["somethingelse"]=>  // <-- is here now in it's own group with no code added
  array(1) {
    ["somethingelse_12"]=>
    int(99)
  }
}

Upvotes: 5

Alberto
Alberto

Reputation: 672

This is a working example:

$a = array ( 'operator_15' => 3, 'fiter_15' => 4, 'operator_17' => 5, 'fiter_17' => 5, 'operator_19' => 4, 'fiter_19' => 2 );
$fiter_array = array();
$operator_array = array();
foreach($a as $key => $val)
{
    if(strpos($key, 'fiter') !== false)
    {
        array_push($fiter_array, $a[$key]);
        // or if you want to maintain the key
        $fiter_array[$key] = $val;
    }
    else
    {
        array_push($operator_array, $a[$key]);
        // or if you want to maintain the key
        $operator_array[$key] = $val;
    }
};
var_dump($fiter_array);
var_dump($operator_array);

Upvotes: 0

shubhangee
shubhangee

Reputation: 539

Give a try with below and see if its solve your problem

$array = array ( 
    'operator_15' => 3,
    'fiter_15' => 4,
    'operator_17' => 5,
    'fiter_17' => 5,
    'operator_19' => 4,
    'fiter_19' => 2 );

$operator=array();
$filter=array();

foreach($array as $key => $value){
    if (strpos($key, 'operator_') !== false) {
        $operator[$key] = $value;
    }

    if (strpos($key, 'fiter_') !== false) {
        $filter[$key] = $value;
    }   
}

print_r($operator);
print_r($filter);

Upvotes: 3

Related Questions