how to remove element from reference array in php? - php

I am using before code to get every first id and remove that id but it show error undefine offset.
I don't understand What i missed in the below code ?
$products = Array
(
[32] => Array
(
[0] => 44
[1] => 45
[2] => 926
[3] => 927
[4] => 930
[5] => 931
)
[41] => Array
(
[0] => 928
[1] => 933
[2] => 969
[3] => 970
[4] => 971
[5] => 972
[6] => 973
[7] => 974
[8] => 975
[9] => 976
[10] => 977
[11] => 978
[12] => 979
[13] => 980
[14] => 981));
$in_array = array();
for($i=0;$i<12;)
{
foreach($products as &$brands):
if(isset($brands[0]))
{
$id = $brands[0];// get the first element
unset( $brands[0]); // have remove that element form products
// But here it show error undefine offset 0
array_push($in_array,$id);
/*if(($key1 = array_search($id, $brands)) !== false) {
unset($brands[$key1]);
}*/
//I tried this too same error
$i++;
}
endforeach;
}

$brands[0] doesn't seem to exist(I only see 32 and 41 in your code).
If you'd like to remove the first element in $products[32] than you need another foreach in your foreach:
foreach($products as $brands) {
foreach($brands as $brand) {
//Here is where you can reach $brand[0](Which is 44 in $products[32])
}
}
If you'd like to remove the first element of the array, you can use array_shift

By the help of mr #CaptainCarl i change my loop it working fine
for($i=0;$i<12;)
{
foreach($products_ids as $key=>$brands):
if(isset($brands[0]))
{
$id = $brands[0];
array_push($in_array,$id);
array_shift($brands);
$i++;
}
$products_ids[$key] = $brands;
endforeach;
}

Related

What is the best approach to create an array having specific key's value from a multidimensional array? [duplicate]

This question already has answers here:
Is there a function to extract a 'column' from an array in PHP?
(15 answers)
Closed 7 months ago.
Hello i have an multidimensional array
each of the array contains key of "id_category"
I am trying to store value of key "id_category" while loop through the multidimensional array.
Here is the array & php compiler
https://paiza.io/projects/H8FwXLAZc438-XA-hnmNHQ?language=php
$save_id_category = [];
foreach($array as $ct){
$save_id_category[] = $ct['id_category'];
}
print_r($save_id_category); // this gets me only one record.
I can loop through all array & save data but that would be not good idea.
Please let me know if we have a better approach
for this.
Thanks
You can use a recursive function to find all the id_category values, first getting all the values at the current level using array_column, then iterating over the children of each array element to add their categories to the list:
function get_categories($array) {
$categories = array_column($array, 'id_category');
foreach ($array as $ct) {
$categories = array_merge($categories, get_categories($ct['children'] ?? array()));
}
return $categories;
}
print_r(get_categories($arrayone));
Output (for your sample data):
Array
(
[0] => 12
[1] => 13
[2] => 15
[3] => 16
[4] => 48
[5] => 68
[6] => 58
[7] => 282
[8] => 17
[9] => 18
[10] => 85
[11] => 52
[12] => 53
[13] => 86
[14] => 54
[15] => 55
[16] => 56
[17] => 217
[18] => 275
[19] => 69
[20] => 70
[21] => 71
[22] => 278
[23] => 59
[24] => 60
[25] => 61
[26] => 283
)

Foreach duplicating when creating object of objects

What I have
So I have a variable named result that is formatted like this:
Array
(
[0] => stdClass Object
(
[description] => dev1
[id] => 09A
[sum] => 52
[completed_pct_completed] => 97.97
[completed_pct_1msec] => 11.44
....
)
[1] => stdClass Object
(
[description] => dev1
[id] => 273
[sum] => 59
[completed_pct_completed] => 94.43
[completed_pct_1msec] => 10.95
....
)
[2] => stdClass Object
(
[description] => dev1.1
[id] => 28A
[sum] => 39
[completed_pct_completed] => 95.55
[completed_pct_1msec] => 20.78
....
)
[3] => stdClass Object
(
[description] => dev1.1
[id] => 28B
[sum] => 31
[completed_pct_completed] => 91.55
[completed_pct_1msec] => 28.78
....
)
....
There are about 250 different objects. The problem with this current order is that the description of each becomes redundant to the point that I just one want to put all the data of each description into an object. Descriptions go by dev1.x, where x can be a different number or letter or whatever, doesn't matter.
What I want to do:
I'm trying to reorder $result into the format below. Pretty much, by traversing each item in the $result array, each description in result will be it's own property in a new object. Inside of each description property will be subitems like id, sum, completed_pct_completed, etc. It will look like this:
stdClass Object
(
[dev1] => stdClass Object
(
[id] => Array
(
[0] => 182
[1] => 218
[2] => 218
[3] => 021
[4] => 186
[5] => 287
[6] => 21A
)
[sum] => Array
(
[0] => 567
[1] => 567
[2] => 567
[3] => 567
[4] => 567
[5] => 567
[6] => 567
)
[completed_pct_completed] => Array
(
[0] => 567
[1] => 567
[2] => 567
[3] => 567
[4] => 567
[5] => 567
[6] => 567
)
[completed_pct_1msec] => Array
(
[0] => 567
[1] => 567
[2] => 567
[3] => 567
[4] => 567
[5] => 567
[6] => 567
)
.........
)
[dev1.1] => stdClass Object
(
[id] => Array
(
[0] => 182
[1] => 329
[2] => 465
[3] => 685
[4] => 686
[5] => 607
[6] => 61A
)
[sum] => Array
(
[0] => 567
[1] => 567
[2] => 567
[3] => 567
[4] => 567
[5] => 567
[6] => 567
)
[completed_pct_completed] => Array
(
[0] => 567
[1] => 567
[2] => 567
[3] => 567
[4] => 567
[5] => 567
[6] => 567
)
[completed_pct_1msec] => Array
(
[0] => 567
[1] => 567
[2] => 567
[3] => 567
[4] => 567
[5] => 567
[6] => 567
)
............
)
............
What I've done so far
So here's how I've constructed what I want so far:
I made an object with properties of each unique description:
$object = new STDClass();
//$flipped is the transposed version of $result, then I got unique names
foreach (array_unique($flipped['description']) as $string)
$object->{$string} = array();
This went perfectly fine. Then, I added the subitems to each description property in $object
$dummyObject = new STDClass();
foreach ($object as $objectKey=>$objectValue) {
foreach ($result[0] as $key=>$value){
if ($key!='description'){
$dummyObject->{$key}=array();
$object->$objectKey=$dummyObject;
}
}
}
This also went fine.
The problem here is inserting the data into each id and summary, etc.. Here's what I've done:
//add data to the subitems
//foreach dev1.x => array
foreach ($object as $key => $nextObject)
{
//foreach array as subitems(id, board, etc.) => array
foreach ($nextObject as $nextKey => $dataArray)
{
$dummyArray = array();
foreach ($result as $array)
{
foreach ($array as $arrayKey => $arrayValue)
{
if ($array->{'description'} == $key) {
if ($nextKey == $arrayKey) {
$dummyArray[]=$arrayValue;
}
}
}
}
$object->{$key}->{$nextKey} = $dummyArray;
}
}
In the end, all the data from the last dev1.x property ends up being overwritten into every single dev1.x property. I've tried adding break; in multiple places hoping that I'd be able to deduce what is going wrong. I have a gut feeling that there's more going on than I know with the foreach statements. Would anyone mind helping me with this?
Thanks
It looks like it may be less complicated than it seems. Unless I'm misunderstanding what the transformation should be, you can do it like this:
foreach ($result as $obj) {
foreach ($obj as $key => $value) {
if ($key != 'description') {
$new_result->{$obj->description}->$key[] = $value;
}
}
}
This should create the object and add the appropriate properties and values all at once.
The reason you're getting the duplication is in this part:
$dummyObject = new STDClass();
foreach ($object as $objectKey=>$objectValue) {
foreach ($result[0] as $key=>$value){
if ($key!='description'){
$dummyObject->{$key}=array();
$object->$objectKey=$dummyObject;
}
}
}
When you do $object->$objectKey=$dummyObject; because you created the object before the loop, you're resetting and reassigning the same object to each $objectKey. So when you fill it with values later, you just end up with multiple copies of whatever the last one was. If you use a copy of the object insteady ($object->$objectKey= clone $dummyObject;) it should work. But it does seem a bit overcomplicated.
Just create keys while iterating:
$data = new stdClass();
foreach ($result as $object) {
$description = $object->description;
isset($data->{$description}) or $data->{$description} = new stdClass();
foreach ($object as $name => $value) {
if ($name === 'description') { continue; }
$data->{$description}->{$name}[] = $value;
}
}
I don't like descriptions as field names though. Access to $data->{'dev1.1'} is ugly. Would pack it into an array of objects, but description property would be just a string and other properties would be aggregated arrays. It would need some changes in procedure (index of descriptions propably).

How to find available batches inside of number range in php

There is a problem that I'm spending some time to figure out a solution.
There is a main number batch. For example 100 - 150(size - 51).
And also there are few sub batches inside of that main batch. For example 105 - 110 and 120 - 130.
I want to get other batches and their batch sizes inside of main batch.
For example
100-104, 111-119 and 131-150
I have tried to find a solution for this but haven't found any solution yet. Is there anyone who can guide me to do this in php or give pseudocode, it will be very helpful for me.
Thanks
Using array_diff, you can find the free spaces in your array of batches.
Then extract from this list the parts without interruption of keys, resulting in each free ranges left.
$mainBatch = range(100, 150);
$subBatch = range(110, 120);
$subBatch2 = range(130,145);
$subBatchesFree = array_diff($mainBatch, $subBatch, $subBatch2);
$remainingBatches = array();
$i = 0;
foreach ($subBatchesFree as $key => $available) {
if (isset($subBatchesFree[$key + 1])) {
// Next key is still in the range
++$i;
} else {
// Next key is in a new range.
// I create the current one and init for the next range
$remainingBatches[] = range($subBatchesFree[$key - $i], $available);
$i = 0;
}
}
print_r($remainingBatches);
Output :
Array
(
[0] => Array
(
[0] => 100
[1] => 101
[2] => 102
[3] => 103
[4] => 104
[5] => 105
[6] => 106
[7] => 107
[8] => 108
[9] => 109
)
[1] => Array
(
[0] => 121
[1] => 122
[2] => 123
[3] => 124
[4] => 125
[5] => 126
[6] => 127
[7] => 128
[8] => 129
)
[2] => Array
(
[0] => 146
[1] => 147
[2] => 148
[3] => 149
[4] => 150
)
)

php multidimensional array path segment combination loop

I am trying to figure a way to get this to work. But I have a hard time thinking out the logics.
I have this array:
Array
(
[0] => Array
(
[0] => news
[1] => {section}
[2] => {slug}
[3] => {*}
)
[1] => Array
(
[0] => {id}
[1] => {*}
)
[2] => Array
(
[0] => {date}
[1] => 25-07-1982
[2] => {section}
[3] => {slug}
[4] => {*}
)
)
That I need to convert to this result:
0 news/{id}/{date}
1 news/{id}/25-07-1982
2 news/{id}/{section}
3 news/{id}/{slug}
4 news/{id}/{*}
5 news/{*}/{date}
6 news/{*}/25-07-1982
7 news/{*}/{section}
8 news/{*}/{slug}
9 news/{*}/{*}
10 {section}/{id}/{date}
11 {section}/{id}/25-07-1982
12 {section}/{id}/{section}
13 {section}/{id}/{slug}
14 {section}/{id}/{*}
15 {section}/{*}/{date}
16 {section}/{*}/25-07-1982
17 {section}/{*}/{section}
18 {section}/{*}/{slug}
19 {section}/{*}/{*}
20 {slug}/{id}/{date}
21 {slug}/{id}/25-07-1982
22 {slug}/{id}/{section}
23 {slug}/{id}/{slug}
24 {slug}/{id}/{*}
25 {slug}/{*}/{date}
26 {slug}/{*}/25-07-1982
27 {slug}/{*}/{section}
28 {slug}/{*}/{slug}
29 {slug}/{*}/{*}
30 {*}/{id}/{date}
31 {*}/{id}/25-07-1982
32 {*}/{id}/{section}
33 {*}/{id}/{slug}
34 {*}/{id}/{*}
35 {*}/{*}/{date}
36 {*}/{*}/25-07-1982
37 {*}/{*}/{section}
38 {*}/{*}/{slug}
39 {*}/{*}/{*}
The input array could contain more than three keys, so the solution I'm looking for should be dynamic. And the result should have the same order as the result shown above.
Does someone know how to do this in a efficient way? Can someone give me a push in the right direction? Thanks a lot! :)
Sth like this
foreach ($array[0] as $val0 )
foreach ($array[1] as $val1 )
foreach ($array[2] as $val2 )
$newArray[] = "$val0/$val1/$val2";
EDIT: for variable array length
function recursive($array , $length = 0){
$retval =array();
if($length < count($array) -1){
foreach ($array[$length] as $val0 )
foreach (recursive($array, $length+1) as $val1)
$retval[] = "$val0/$val1";
}
else
{
foreach ($array[$length] as $val0 )
$retval[] = "$val0";
}
return $retval;
}
print_r(recursive($array));
Just because I like writing functions that mis/manage PHP arrays, I put this together, mainly because I was pretty sure you could avoid recursion — because the structure itself isn't recursive. (My head seems to think that is a rule, I'm sure someone somewhere can prove it wrong).
foreach ( array_reverse($array) as $sub ) {
if ( isset($rem) ) {
$ret = array();
foreach ( $sub as $itm ) {
foreach ( $rem as $val ) { $ret[] = "$itm/$val"; }
}
$rem = $ret;
}
else {
$rem = $sub;
}
}
The output found in $rem is as follows:
Array (
[0] => news/{id}/{date}
[1] => news/{id}/25-07-1982
[2] => news/{id}/{section}
[3] => news/{id}/{slug}
[4] => news/{id}/{*}
[5] => news/{*}/{date}
[6] => news/{*}/25-07-1982
[7] => news/{*}/{section}
[8] => news/{*}/{slug}
[9] => news/{*}/{*}
[10] => {section}/{id}/{date}
[11] => {section}/{id}/25-07-1982
[12] => {section}/{id}/{section}
[13] => {section}/{id}/{slug}
[14] => {section}/{id}/{*}
[15] => {section}/{*}/{date}
[16] => {section}/{*}/25-07-1982
[17] => {section}/{*}/{section}
[18] => {section}/{*}/{slug}
[19] => {section}/{*}/{*}
[20] => {slug}/{id}/{date}
[21] => {slug}/{id}/25-07-1982
[22] => {slug}/{id}/{section}
[23] => {slug}/{id}/{slug}
[24] => {slug}/{id}/{*}
[25] => {slug}/{*}/{date}
[26] => {slug}/{*}/25-07-1982
[27] => {slug}/{*}/{section}
[28] => {slug}/{*}/{slug}
[29] => {slug}/{*}/{*}
[30] => {*}/{id}/{date}
[31] => {*}/{id}/25-07-1982
[32] => {*}/{id}/{section}
[33] => {*}/{id}/{slug}
[34] => {*}/{id}/{*}
[35] => {*}/{*}/{date}
[36] => {*}/{*}/25-07-1982
[37] => {*}/{*}/{section}
[38] => {*}/{*}/{slug}
[39] => {*}/{*}/{*}
)
Also, for those that like their arrays multidimensional, this might come in handy (although I'd hate to think what the overheads are for such a code golfed version). Just to be clear, this second example doesn't create the string list as requested by the OP, but a hierarchical array structure instead.
foreach ( array_reverse($array) as $sub ) {
$rem = isset($rem)
? array_combine($sub, array_fill(0, count($sub), $rem))
: $sub
;
}
This generates (again in $rem):
Array (
[news] => Array (
[{id}] => Array (
[0] => {date}
[1] => 25-07-1982
[2] => {section}
[3] => {slug}
[4] => {*}
)
[{*}] => Array (
[0] => {date}
[1] => 25-07-1982
[2] => {section}
[3] => {slug}
[4] => {*}
)
)
[{section}] => Array (
[{id}] => Array (
[0] => {date}
[1] => 25-07-1982
[2] => {section}
[3] => {slug}
[4] => {*}
)
... and so on
Now if only PHP had a join_recursive that included keys.
(it would be almost pointless, save for helping with the above).

Php, printing a 3d array into a table

Basically i need to sort some data into the top 5 best sales.
I've managed to group the 3 arrays i've used using.
$c = array_combine($PriceArray,$namesArray,$ProductArray);
krsort($c);
Price array being the total. (Bit of a silly name, i just realised)
namesarray is the array of names
and product array is the list of product codes
I need to print it in a table like
"|£3.45|Jelly Beans | 120|"
so they have their own column, but at the moment it's printing it like
| 3.45| array | array|
and i use
echo '<td>'.$ProductArray[$i].'</td>'.'<td>'.$year.'</td>'.'<td>'.array_keys($c,$c[$i]).'<td>'. $PriceArray[$i].'</td>';
to print it.
Thanks in advance
Array
(
[0] => 77358.47
[1] => 111004.98
[2] => 227194.9
[3] => 84645.75
[4] => 29693.58
[5] => 198867.2
[6] => 110779.5
[7] => 210530.62
[8] => 102916.79
[9] => 186630.75
[10] => 140143.24
[11] => 48984.48
[12] => 74759.34
[13] => 204793.14
[14] => 82192.5
[15] => 167402.7
[16] => 58232.72
[17] => 216302.32
[18] => 26353.92
[19] => 149993.1
)
Array
(
[0] => Jelly beans
[1] => Banana milkshake powder
[2] => Edam Cheese
[3] => Hairnet
[4] => Aubergine jam
[5] => White bread
[6] => Brown bread
[7] => Purple bread
[8] => Plain flour
[9] => Striped flour
[10] => Soft tissues
[11] => Anti personnel mines
[12] => Chicken fillets
[13] => Beef cubes
[14] => Marshmallows
[15] => Fizzy carrot juice
[16] => Low fat lard
[17] => Suet dumpling mix
[18] => Gravy powder
[19] => Cherry pie filling
)
Array
(
[0] => 121
[1] => 122
[2] => 123
[3] => 124
[4] => 125
[5] => 126
[6] => 127
[7] => 128
[8] => 129
[9] => 130
[10] => 131
[11] => 132
[12] => 133
[13] => 134
[14] => 135
[15] => 136
[16] => 137
[17] => 138
[18] => 139
[19] => 140
)
Product Code Year Name Sales Total
Zip function blatantly stolen from: zip function from SO
function zip() {
$args = func_get_args();
$zipped = array();
$n = count($args);
for ($i=0; $i<$n; ++$i) {
reset($args[$i]);
}
while ($n) {
$tmp = array();
for ($i=0; $i<$n; ++$i) {
if (key($args[$i]) === null) {
break 2;
}
$tmp[] = current($args[$i]);
next($args[$i]);
}
$zipped[] = $tmp;
}
return $zipped;
}
function cmp($a, $b)
{
if($a[0] == $b[0]){
return 0;
}
return ($a[0] < $b[0]) ? -1 : 1;
}
$PriceArray = array( 4.56, 1.23, 7.89 );
$namesArray = array( 'ab', 'cd', 'ef' );
$ProductArray = array( '11', '22', '33' );
$c = zip($PriceArray, $namesArray, $ProductArray);
usort($c, 'cmp');
foreach($c as $prices)
{
//$prices[0] == price
//$prices[1] == name
//$prices[2] == code
echo "{$prices[0]}|{$prices[1]}|{$prices[2]}\n";
prints:
1.23|cd|22
4.56|ab|11
7.89|ef|33
I am using the zip-function that is available natively in Python to combine N-arrays and "zip" them together.
So take index 0 of all given arrays, and make that a new array entry. Do that for all indices available.
The cmp function takes two variables, in this case two arrays, where index-0 = price, 1 = name and 2 = code. You obviously want to sort by ascending by price thus we are comparing the price index. This results in a new/sorted array based on price.
You can also substitude the usort($c, 'cmp'); call with the following:
usort($c, function($a, $b){
if($a[0] == $b[0]){
return 0;
}
return ($a[0] < $b[0]) ? -1 : 1;
});
However, this is only available in PHP version >= 5.3
Just put the keys and values into new arrays.
$NewNamesArray = array_values($c); $NewPriceArray = array_keys($c)

Categories