1

Yes, this has been answered countless times by using different methods, in most cases it works but not on my case, please allow me to explain.

I'm building an array from a CSV file, that was the easy part, the difficult part is, I have is that I have to build another array from the first array grouping the results based on one key value, the problem is that this value is not an array, nor a simple string...
This is a sample from the array of the CSV file

[0] => Array
     (
       [key_1] => FOO
       [cats] => /30/
       [key_2] => FTU-1
     )
[1] => Array
     (
       [key_1] => FOO
       [cats] => /30/
       [key_2] => FTU-2
     )
[2] => Array
     (
       [key_1] => FOO
       [cats] => /30/10/
       [key_2] => FTU-3
     )
[3] => Array
     (
       [key_1] => FOO
       [cats] => /15/
       [key_2] => FTU-4
     )
[4] => Array
     (
       [key_1] => FOO
       [cats] => /10/
       [key_2] => FTU-5
     )
[0] => Array
     (
       [key_1] => FOO
       [cats] => /15/
       [key_2] => FTU-6
     )

The final array has to look like this based on the column cats:

[30] => Array 
        (
           [0] => Array 
                 (
                   [key_1] => FOO
                   [cats] => /30/
                   [key_2] => FTU-1
                 )
           [1] => Array
                 (
                   [key_1] => FOO
                   [cats] => /30/
                   [key_2] => FTU-2
                 )
           [1] => Array
                 (
                   [key_1] => FOO
                   [cats] => /30/10/
                   [key_2] => FTU-3
                 )
[15] => Array 
        (
           [0] => Array 
                 (
                   [key_1] => FOO
                   [cats] => /15/
                   [key_2] => FTU-4
                 )
           [1] => Array
                 (
                   [key_1] => FOO
                   [cats] => /15/
                   [key_2] => FTU-6
                 )
[10] => Array 
        (
           [0] => Array 
                 (
                   [key_1] => FOO
                   [cats] => /30/10/
                   [key_2] => FTU-3
                 )
           [1] => Array
                 (
                   [key_1] => FOO
                   [cats] => /10/
                   [key_2] => FTU-5
                 )

I was looking in to this This answer which is the closest to what I need, but didn't work, that's why I'm asking for help.

Update: I think I just solved it...

foreach($firstarr as $k => $v) {
  $cats = array_filter(explode('/', $v['cats']));
  foreach($cats as $ks=>$vs) {
    if(stripos($v['cats'], $vs)){
      $pp[$vs][] = $v;
    }
  }
}

looking good.

Community
  • 1
  • 1
Tanker
  • 983
  • 3
  • 13
  • 41

3 Answers3

1

Maybe you help this code:

function arrayByOneKey($array, $keyName)
{
    $result = [];
    foreach ($array as $item)
    {
        $keys = explode('/', (string)$item[$keyName]);
        foreach($keys as $key)
        {
            if($key == '')
            {
                continue;
            }
            $result[$key][] = $item;
        }
    }
    return $result;
}

$array = [
    [
        'key_1' => 'FOO',
        'key_2' => 'FTU-1',
        'cats' => '/15/'
    ],
    [
        'key_1' => 'FOO',
        'key_2' => 'FTU-2',
        'cats' => '/15/'
    ],
    [
        'key_1' => 'FOO',
        'key_2' => 'FTU-3',
        'cats' => '/30/10/'
    ],
    [
        'key_1' => 'FOO',
        'key_2' => 'FTU-4',
        'cats' => '/30/10/0'
    ]
];

$array = arrayByOneKey($array, 'cats');
var_dump($array);

Result:

array(4) {
  [15]=>
  array(2) {
    [0]=>
    array(3) {
      ["key_1"]=>
      string(3) "FOO"
      ["key_2"]=>
      string(5) "FTU-1"
      ["cats"]=>
      string(4) "/15/"
    }
    [1]=>
    array(3) {
      ["key_1"]=>
      string(3) "FOO"
      ["key_2"]=>
      string(5) "FTU-2"
      ["cats"]=>
      string(4) "/15/"
    }
  }
  [30]=>
  array(2) {
    [0]=>
    array(3) {
      ["key_1"]=>
      string(3) "FOO"
      ["key_2"]=>
      string(5) "FTU-3"
      ["cats"]=>
      string(7) "/30/10/"
    }
    [1]=>
    array(3) {
      ["key_1"]=>
      string(3) "FOO"
      ["key_2"]=>
      string(5) "FTU-4"
      ["cats"]=>
      string(8) "/30/10/0"
    }
  }
  [10]=>
  array(2) {
    [0]=>
    array(3) {
      ["key_1"]=>
      string(3) "FOO"
      ["key_2"]=>
      string(5) "FTU-3"
      ["cats"]=>
      string(7) "/30/10/"
    }
    [1]=>
    array(3) {
      ["key_1"]=>
      string(3) "FOO"
      ["key_2"]=>
      string(5) "FTU-4"
      ["cats"]=>
      string(8) "/30/10/0"
    }
  }
  [0]=>
  array(1) {
    [0]=>
    array(3) {
      ["key_1"]=>
      string(3) "FOO"
      ["key_2"]=>
      string(5) "FTU-4"
      ["cats"]=>
      string(8) "/30/10/0"
    }
  }
}

UPDATE

array_filter - elegant solution BUT category with id 0 will be ignored. And if so, then !empty($key) In the cycle better than array_filter - as it also passes through the array elements

Maxim Tkach
  • 1,457
  • 9
  • 21
  • This is the same logic on my update,. see, the if($key == "") in your code, instead I'm using array_filter() which serves the same purpose, your answer was posted a min after my update, SO doesn't allow me to choose an answer just yet... – Tanker May 15 '16 at 20:30
  • array_filter - elegant solution BUT category with id 0 will be ignored. And if so, then !empty($key) In the cycle better than array_filter - as it also passes through the array elements – Maxim Tkach May 15 '16 at 20:35
0

You can get the key from explode('/', $item['cats'])[1]:

$newArray = [];
foreach($originalArray as $item) {
    $key = explode('/', $item['cats'])[1];
    $newArray[$key][] = $item;
}
Fabricator
  • 12,381
  • 2
  • 23
  • 36
0

This may be a twisted work-around but I am willing to bet it does the trick:

        <?php

        $arrResultant = array();

        foreach($arr as $intKey=>$arrData){
            $stripped   = preg_replace("#^\/#", "", $arrData['cats']);
            $arrParts   = preg_split("#\/#", $stripped);
            $intCat1    = isset($arrParts[0])? $arrParts[0]:null;
            $intCat2    = isset($arrParts[1])? $arrParts[1]:null;
            if(!array_key_exists($intCat1, $arrResultant)){
                $arrResultant[$intCat1] = array();
                if( stristr($arrData["cats"], $intCat1) ){
                    $arrResultant[$intCat1][] = $arrData;
                }
            }else{
                if( stristr( $arrData["cats"], $intCat1) ){
                    $arrResultant[$intCat1][] = $arrData;
                }
            }
            if(!array_key_exists($intCat2, $arrResultant) && !is_null($intCat2)){
                $arrResultant[$intCat2] = array();
                if( stristr($arrData["cats"], $intCat2) ){
                    $arrResultant[$intCat2][] = $arrData;
                }
            }else{
                if( stristr( $arrData["cats"], $intCat2) ){
                    $arrResultant[$intCat2][] = $arrData;
                }
            }
        }

        var_dump($arrResultant);

Try it out and let us know how it went....

Poiz
  • 7,306
  • 2
  • 11
  • 17