With the following bit of code I'm trying to get the key's of each sub-array that I will need at this part of the script. It's working so I'm not too worried about this, I just think there should be a pre-built function to do the same thing.

foreach($myArray['ico'] as $k => $v) {
    if(count($v) == 2) {
        $kidsKey = $k;
    }
    if($v['type'] == 'bags') {
        $luggKey = $k;
    }
}

How would you guys go about doing this? My only concern is that the array may grow with time and I'm wasting memory just to get 2 keys at this point.

For academic purposes, lets belive I have no control over the array creation so changing the key at the start isn't an option.

Member Avatar for diafol

Could you give us a print_r output of the array, so we can see the structure please?

btw - array_map, array_filter may be useful?

The array structure is something like this:

$myArray = array(
    "someItem1" => array(
        "someContent" => "value",
    ),
    "ico" => array(
        0 => array(      // <--I need this key for $luggKey
            "class" => "classNameA",
            "title" => "This is a title",
            "type" => "bags",
        ),
        1 => array(      // <--I need this key for $kidsKey
            0 => array(
                "class" => "classNameB",
                "title" => "This is another title",
                "type" => "baby",
            ),
            1 => array(
                "class" => "classNameC",
                "title" => "This is yet another title",
                "type" => "child",
            ),
        ),
    ),
    "someItem2" => array(
        "someContent" => "value",
    ),
);

You can paste this array and the block from my 1st post here and add the following to see it's giving out the right values.

echo '$kidsKey = '.$kidsKey.';<br>';
echo '$luggKey = '.$luggKey.';<br>';

I did look at array_map and array_filter before looping through it, but either it's not what I'm looking for, or I didn't understand how to go from the given examples to what I actually needed.

Member Avatar for diafol

Is kidskey always 1 and luggkey always 0? If so, I don't see why you need a loop at all:

if(isset($myArray['ico'][0]['type']) && $myArray['ico'][0]['type'] == 'bags')
{
    $luggkey = 0; //??
}

if(count($myArray['ico']) == 2)
{
    $kidskey = 1; //??
}

Either that or I don't get it at all.

Oh I'm sorry, I forgot to say that although the structure is the same, the positions might be diferent and there might be more or less icons in that sub-array and that's where the key's will change.

The back office will allow to assign order to those icons which will then be properly ordered by the db query. Here is where I could actually assign a stringed key to those and the problem would be solved. I might just do that, but since I didn't find another way, I'd like to know if there's something I overlooked while trying to find a way to pull it off.

And where you test this condition if(count($myArray['ico']) == 2) you wouldn't hit the target as there could be more icons in ['ico'], it would have to be something like if(count($myArray['ico'][?]) == 2).

Member Avatar for diafol

I'm finding it very difficult to see what you're trying to do. Could you include an example of an array with multiple ico items?

The array structure is odd. How are you creating it? Maybe you need to create associative keys instead of numeric ones.

True, I could create the array with associative keys, that's how I'm considering as a solution to avoid the loop, I just posted the question to figure out if there's actually a way of doing it with numeric keys where I wouldn't know the value. Just trying to figure out if there's something extra I don't know how to do that could serve me in the future when I'm unable to change the base structure of an array.

So lets go to the concrete example of what the array means. This array is going to describe a "car", this car will have features "extras" like luggage capacity (bags), baby seats and booster seats capacity (kids -> baby, child), air conditioner, tolls, wheelchair option, wifi. All of these might appear as an icon on the block that describes the car. So each car will have it's own ['ico'] sub-array and that's why the number of icons will change.

Let's go to the full array with several cars:

$myMainArray = array(
    "myArrayForCar1" => array(
        "someItem1" => array(
            "someContent" => "value",
            ...
        ),
        "ico" => array(
            0 => array(
                "type" => "bags",
                ...
            ),
            1 => array(
                0 => array(
                    "type" => "baby",
                    ...
                ),
                1 => array(
                    "type" => "child",
                    ...
                ),
            ),
        ),
        "someItem2" => array(
            "someContent" => "value",
            ...
        )
    ),
    "myArrayForCar2" => array(
        "someItem1" => array(
            "someContent" => "value",
            ...
        ),
        "ico" => array(
            0 => array(
                "type" => "wifi",
            ),
            1 => array(
                "type" => "bags",
            ),
            2 => array(
                0 => array(
                    "type" => "baby",
                ),
                1 => array(
                    "type" => "child",
                ),
            ),
            3 => array(
                "type" => "tolls",
            ),
        ),
        "someItem2" => array(
            "someContent" => "value",
            ...
        )
    ),
    ...
);

The function that then creates each car block will take as a parameter the corresponding sub-array myArray like so:

createCarBlock($myMainArray['myArrayForCar1']);

function createCarBlock($thisCar) {
    //do things with this car
    //this is where i need the keys
}

So each sub-array has a variable number of items depending on what has been configured in the database. So yes I can change the key from numbered to associative, I will do that since it will reduce processing loops all the time, but I'm just trying to see if I skip something while trying to learn how to handle arrays. If the only options are loop the array and change the keys, I did my job looking for solutions properly. If there's another way, it's something I missed and that's what I need to learn.

Member Avatar for diafol

Ok, thanks - I'll have a think.

//EDIT

We can filter the main subarrays that have ico and bags like this:

function filter($arr, $type)
{
    $reduced = array_filter($arr, function($array) use($type){
        return (isset($array['ico']) && array_filter($array['ico'], function($array2) use($type){
             return isset($array2['type']) && $array2['type'] == $type;
        }));    
    });

    return $reduced;
}

$type = 'bags';

echo "<pre>";
print_r(filter($myMainArray,$type));
echo "<pre>";

perhaps it doesn't seem to do anything, but if you change the array:

"myArrayForCar1" => array(
        "someItem1" => array(
            "someContent" => "value"
        ),
        "ico" => array(
            0 => array(
                "type" => "bags",

to

"myArrayForCar1" => array(
            "someItem1" => array(
                "someContent" => "value"
            ),
            "ico" => array(
                0 => array(
                    "type" => "bags2", //here

then you should see that myArrayForCar1 does not show in the resulting array.

But that's not quite what you want, I know. A loop would be easiest, but I'm trying to think about various array functions that could do the key/index extraction 'easily'

Yeah, I need the keys to use later on, that filter function would return the sub-arrays that contain a certain type and that would force me to test if it's an array or not after each use since providing the result as a parameter might throw an error for not beeing an array. As with my current solution it's always an array and won't throw errors.

Hope you're enjoying the puzzle as much as I did, although I only got the loop as a solution.

Hi,
May I add someting?

there is a PHP object called ArrayObject ArrayIterator method and I think (but not sure) there is also a method for it called key. Just don't have time to look it up, but it is pretty much for getting the key of an array. Though I am not sure what is the memory cost for Iterator, it should let you write codes a lot shorter.

Member Avatar for diafol

May I add someting?

The more the merrier. Interesting set of SPLs, however I couldn't find a function / method that didn't involve looping the array or array object.

@veedeoo I know about the ArrayIterator, although I never got to it. But I'll try to give those a looksie. Thanks for pointing them out, I had forgotten about them as I never used them.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.