PHP Loop through array with no index names - php

In PHP I have this structure of Array (some are empty, some not, some are multiple items):
Array
(
[0] => Array
(
)
[1] => Array
(
[0] => 16534
)
[2] => Array
(
)
[3] => Array
(
[0] => 16532
[1] => 16533
)
[4] => Array
(
)
[5] => Array
(
[0] => 14869
)
}
I want to loop through this array, so as the result I get only the numbers (all of them).
I tried it this way:
foreach ($myarray as $item) {
echo '<pre>' . print_r($item) . '</pre>';
// $result[] = $this->myMethod($item);
}
So in foreach I want to use all the items from array in my method.
However when I echo the $item in the loop, I have something like this:
Array ( )
Array ( [0] => 16534 )
Array ( )
Array ( [0] => 16532 [1] => 16533 )
Array ( )
Array ( [0] => 14869 )
So still arrays (also the empty ones), and not numbers.
Can you please help with this?
UPDATE: I just noticed, some of the arrays looks like this:
[6] => Array
(
[0] => Array
(
[id] => 269
[hours] => 21.0
)
)
[7] => Array
(
[0] => Array
(
[0] => Array
(
[id] => 2
[hours] => 12.0
)
[1] => Array
(
[id] => 7
[hours] => 24.0
)
)
[1] => Array
(
[0] => Array
(
[id] => 2
[hours] => 5.0
)
[1] => Array
(
[id] => 7
[hours] => 0.583
)
)
)
but here the solution works not.
This one seems working but it is now brutal foreach in foreach solution:
foreach ($myarray as $item2) {
foreach ($item2 as $key2 => $val2) {
if (isset($val2)) {
foreach ($val2 as $key4 => $val4) {
echo $val4['id'].',';
}
}
}
}

Just merge the array which will also remove the empties:
foreach(array_merge(...$myarray) as $item) {
// echo '<pre>' . print_r($item) . '</pre>';
$result[] = $this->myMethod($item);
}
This will also work and may be faster:
$result = array_map([$this, 'myMethod'], array_merge(...$myarray));
If you have an old PHP version you'll have to use array() instead of [] and:
call_user_func_array('array_merge', $myarray)

You are only looping through the main array.That's the reason why you are getting an array when you are printing the result set.(because those values are stored in sub arrays and you are not looping them.)
And to remove the sub arrays with empty values I'll use isset() so that you will get only the values.
Change your code into this.
foreach ($myarray as $item) {
foreach($item as $key=>$val){
if(isset($val){
$values[] = $val;
// $result[] = $this->myMethod($values);
}
}
}

Related

Convert Complex array to simple one (for CSV)

I want to convert my complex array to simpler one for exporting that converted simpler array to the CSV file.
Currently my array structure is like:
Array
(
[0] => Array
(
[_source] => Array
(
[block] => Array
(
[0] => Kurud
)
[district] => Array
(
[0] => Dhamtari
)
[state] => Array
(
[0] => Chhattisgarh
)
)
)
[1] => Array
(
[_source] => Array
(
[block] => Array
(
[0] => North-Bangeluru
)
[district] => Array
(
[0] => Bangalore
)
[state] => Array
(
[0] => Karnataka
)
)
)
)
and I want to convert above array to the below given format:
array(
array("block", "district", "state"),
array("Kurud","Dhamtari","Chhattisgarh"),
array("North-Bangeluru","Bangalore","Karnataka")
)
So keys will be the first element and then each element with his data.
This is what I tried:
foreach ($array as $key => $value) {
if (is_array($value)) {
$result = array_merge($result);
}
else {
$result[$key] = $value;
}
}
print_r(result);
thanks in advance...
How about:
$keys = array_keys($arr[0]["_source"]);
$res[] = $keys;
foreach($arr as $e) {
$temp = [];
foreach($keys as $k)
$temp[] = $e["_source"][$k][0];
$res[] = $temp;
}
Reference: array-keys
Live example: 3v4l

Get the difference between one sub-Array or multiple sub-Arrays in a multidimensional Array

I have following multidimensional Array and I want to get the difference, if there is just one sub Array or multiple in that array.
For Example:
In Array [1] there is just one sub Array [example]
In Array [2] there are two sub Arrays [example]
[content] => Array
(
[...]
[1] => Array
(
[example] => Array
(
[value] => GET THIS
[attr] => Array
(
[...]
)
)
)
[2] => Array
(
[example] => Array
(
[0] => Array
(
[value] => GET THIS
[attr] => Array
(
[...]
)
)
[1] => Array
(
[value] => GET THIS
[attr] => Array
(
[...]
)
)
)
)
Now to get the [value] from the first Array I would try:
foreach ($content as $example) {
echo($content['example']['value']);
}
And to get each [value] from the second Array I would try:
foreach ($content as $example) {
foreach ($example as $values) {
echo($value['value']);
}
}
So far so good but how do I decide which function to run? Am I missing something?
Is there an if-statement which can help me there?
Something like:
if(multiple sub-arrays){
// do first code example
} else {
// do second code example
}
I simply want a method to get all values called [value] out of the array.
Thank you in advance!
The most obvious solution is to change function which generates your content array so as it always generates sub arrays in a format like:
[content] => Array
(
[...]
[1] => Array
(
[example] => Array
(
[0] => Array
(
[value] => GET THIS
[attr] => Array
(
[...]
)
)
)
)
[2] => Array
(
[example] => Array
(
[0] => Array
(
[value] => GET THIS
[attr] => Array
(
[...]
)
)
[1] => Array
(
[value] => GET THIS
[attr] => Array
(
[...]
)
)
)
)
But if you don't have such option - then use a simple check:
foreach ($content as $item) {
// here check if your `$item` has an `value` subkey under `example` key
if (array_key_exists('value', $item['example'])) {
echo($item['example']['value']);
} else {
foreach ($item['example'] as $values) {
echo ($values['value']);
}
}
}
Assuming that your final dimension allways as a 'value' node:
function arrayIterate($array){
foreach ($content as $example) {
if(!isset($example['value'])){
arrayIterate($example);
}else{
echo($example['value']);
}
}
}

PHP How to restructure an array?

I have an array that I'd like to restructure. I want to group items by turn. I can figure out how to extract data from the array using foreach($arr['history'] as $obj) my issue is with populating a new array using a loop.
Currently it looks like this:
Array (
[history] => Array (
[id] => 23452435
[legend] => Array (
[0] => Array (
[player] => me
[turn] => 1
[card] => Array (
[name] => foo
)
)
[1] => Array (
[player] => me
[turn] => 1
[card] => Array (
[name] => bar
)
)
[2] => Array (
[player] => opponent
[turn] => 1
[card] => Array (
[name] => derp
)
)
[3] => Array (
[player] => opponent
[turn] => 2
[card] => Array (
[name] => hoo
)
)
)
))
I want it to look like the following, but I can't figure out how to automatically create and populate this structure. This is an array with a sub-array for each turn, containing an array for me and opponent
Array (
[0] => Array (
[me] => Array (
[0] => foo
[1] => bar
)
[opponent] = Array (
[0] => derp
)
)
[1] => Array (
[me] => Array ()
[opponent] => Array (
[0] => hoo
)
))
Thanks.
Edit:
This is what I needed. Thanks for the answers.
$result = [];
foreach ($arr['history'] as $historyItem) {
foreach ($historyItem['legend'] as $list) {
$result[$list['turn']][$list['player']][] = $list['card']['name'];
}
}
Try this:
$result = [];
foreach ($data['history']['legend'] as $list) {
$result[$list['turn']-1][$list['player']][] = $list['card']['name'];
}
Fiddle it! http://ideone.com/BtKOKJ
You can just start adding data to the new array. PHP is extremely forgiving.
$historyByTurns = array();
foreach ($arr['history'] as $historyItem) {
foreach ($historyItem['legend'] as $legendItem) {
$turn = $legendItem['turn'];
$player = $legendItem['player'];
if (!array_key_exists($turn, $historyByTurns)) {
$historyByTurns[$turn] = array();
}
if (!array_key_exists($player, $historyByTurns[$turn])) {
$historyByTurns[$turn][$player] = array();
}
foreach ($legendItem as $card) {
$historyByTurns[$turn][$player][] = $card['name'];
}
}
}
You will have to test it, as I have no way to do that ATM.

Implode an multidimensional array by keys and values with PHP

I want to join the array keys to a filepath with the value at the end as file itself (the array below is a "filetree")
Array (depth, size and keynames are dynamic):
[0] => bla.tif
[1] => quux.tif
[foo] => Array (
[bar] => Array (
[lorem] => Array (
[1] => ipsum.tif
[2] => doler.tif
)
)
)
[bar] => Array (
[qux] => Array (
[baz] => Array (
[1] => ipsum.tif
[2] => ufo.tif
)
)
)
This result would be fine:
[0] => bla.tif
[1] => quux.tif
[2] => foo/bar/lorem/ipsum.tif
[3] => foo/bar/lorem/doler.tif
[4] => bar/qux/baz/ipsum.tif
[5] => bar/qux/baz/ufo.tif
Maybe there is also a pure PHP solution for that. I tried it with array_map but the results weren't fine enough.
I would use a recursive function to collapse this array. Here's an example of one:
function collapse($path, $collapse, &$result)
{
foreach($collapse AS $key => $value)
{
if(is_array($value))
{
collapse($path . $key . "/", $value, $result);
continue;
}
$result[] = $path . $value;
}
}
And here's how to use:
$result = array();
$toCollapse = /* The multidimentional array */;
collapse("", $toCollapse, $result);
and $result would contain the "imploded" array

Remove item from multidimensional array php

Here is the array:
[cart] => Array
(
[ProductId] => Array
(
[0] => P121100001
[1] => P121100002
)
[SellerId] => Array
(
[0] => S12110001
[1] => S12110001
)
[SpecifyId] => Array
(
[0] => 1
[1] => 2
)
[Quantity] => Array
(
[0] => 1
[1] => 1
)
[Price] => Array
(
[0] => 12
[1] => 29
)
[TotalPrice] => 41
)
I have the ProductId and I want to remove all the other items matching P121100002's key.
Is there an easy way to do this I can't can seem to come up with one?
You can loop through the full array and use unset() to, well, "unset" the specified index:
$index = array_search($cart['ProductId'], 'P121100002');
if ($index !== false) {
foreach ($cart as $key => $arr) {
unset($cart[$key][$index]);
}
}
The slight caveat to this approach is that it may disrupt your index orders. For instance, say you have:
[ProductId] => Array (
[0] => P121100001
[1] => P121100002
[2] => P121100003
)
And you want to remove P121100002, which has a corresponding index of 1. Using unset($cart['ProductId'][1]) will cause your array's to become:
[ProductId] => Array (
[0] => P121100001
[2] => P121100003
)
This may be something to remain concerned with if you're going to use a for loop to iterate through in the future. If it is, you can use array_values() to "reset" the indexes in the unset() loop from above:
foreach ($cart as $key => $arr) {
unset($cart[$key][$index]);
$cart[$key] = array_values($cart[$key]);
}
foreach($yourArray['ProductId'] as $key => $value) {
if ($value == $productIdToRemove) {
foreach($yourArray as $deleteKey => $deleteValue) {
unset($yourArray[$deleteKey][$key]);
}
break;
}
}
Use array_key_exists along with the unset() function

Categories