Undefined index error while key exists in array - php

I'm pulling my hair on a proble which seems very simple, but I can't find a solution.
I have a simple $row array here :
array:2 [▼
"reference" => "ABCDEF"
"quantity" => "10"
]
I'm trying to parse it and retrieve quantities per reference using :
$line = [
'ref' => strtoupper($row["reference"]),
'quantity' => $row["quantity"]
];
I'm looping through array of lines using this code:
foreach ($rows as $row) {
$line = [
'ref' => strtoupper($row['reference']),
'quantity' => $row['quantity']
];
}
As a test, my main array $rows has 2 lines :
^ array:3 [▼
0 => array:2 [▼
0 => "ABCDEF"
1 => "10"
]
1 => array:2 [▼
0 => "WXCVBN"
1 => "3"
]
2 => array:1 [▼
0 => null
]
]
However, I'm getting the following error :
Undefined index: reference
Strangely enough, if I comment out the
'ref' => strtoupper($row["reference"]),
line, I can get the "quantity" value with no issue...
I know the key is in there, since the debug of the $row object gives the above result.
It must be dead simple... but I can't find the solution...
If anyone could please help ?

So apparently the $row variable a row from a bigger array that is used in a foreach loop.
This might be the solution to your problem.
$array = [
[ "reference" => "ABC", "quantity" => "10"],
[ "reference" => "ABC", "quantity" => "10"],
[ "reference" => "ABC", "quantity" => "10"],
];
$line[] = '';
foreach($array as $row)
{
$line['ref'] = $row['reference'];
$line['quantity'] = $row['quantity'];
}
In this example $array is your bigger array, i use it to test the example.
After that i create a empty array $line to append the "new" data.
Could you try this?
Edit:
After taking a look at your loop and the array i noticed that your array doesnt have a reference key. Can you try strtoupper(row[0])?

Viewing your code seems that you convert $row array to $line without rewrite key in new array.
your code
foreach ($rows as $row) {
$line = [
'ref' => strtoupper($row['reference']),
'quantity' => $row['quantity']
];
}
With your rewrite you can access $line data by index, not by key
array:3 [▼
0 => array:2 [▼
0 => "ABCDEF"
1 => "10"
]
...
]
My solution
If you want to access your $line data by key, you need to rewrite your loop as:
foreach($rows as $rowData) {
foreach($rowData as $rowKey => $rowValue) {
$data = [
'ref' => $rowKey => strtoupper$($rowValue),
'quantity' => $row['quantity']
];
}
$line[] = $data;
}

Related

Merge arrays in laravel including keys

I have 2 arrays and I want to merge them. (I can merge them) but I also need to include their unique keys in merged results and that part I cannot achieve.
sample
$prices = [
['112802' => "500000"],
['113041' => "1000000"],
];
$notes = [
['112802' => "note 2"],
['113041' => "note 1"],
];
$collection = collect($prices);
$zipped = $collection->zip($notes);
$zipped->toArray();
Unique keys are 112802 and 113041.
When I merge my array all I get is this:
[
[
"1000000",
"note 1"
],
[
"500000",
"note 2"
]
]
What I'm looking for is like this:
[
[
"id" => "112802",
"price" => "500000",
"note" => "note 2",
],
[
"id" => "113041",
"price" => "1000000",
"note" => "note 1",
]
}]
any suggestion?
This does what you want with the data you provide.
NOTE it will only work if your 2 arrays are the same size and the the keys are in the same order.
If this data comes from a database, it is likely it could have been produced in the format you actually wanted rather than having to fiddle with the data post fetch.
$prices = [
['112802' => "500000"],
['113041' => "1000000"],
];
$notes = [
['112802' => "note 2"],
['113041' => "note 1"],
];
$new = [];
foreach ($prices as $i=>$pr){
$k = key($pr);
$new[] = [ 'id' => $k,
'price' => $pr[$k],
'note' => $notes[$i][$k] ];
}
print_r($new);
RESULT
Array
(
[0] => Array (
[id] => 112802
[price] => 500000
[note] => note 2
)
[1] => Array (
[id] => 113041
[price] => 1000000
[note] => note 1
)
)
Here's another solution using some of Laravel's Collection methods.
It's not the most elegant, but it can be a starting point for you.
$prices = collect([
['112802' => "500000"],
['113041' => "1000000"],
])->mapWithKeys(function($item) {
// This assumes that the key will always be the ID and the first element is the price.
// Everythng else for each element will be ignored.
$id = array_keys($item)[0];
return [$id => ["id" => $id, "price" => reset($item)]];
});
$notes = collect([
['112802' => "note 2"],
['113041' => "note 1"],
])->mapWithKeys(function($item) {
$id = array_keys($item)[0];
return [$id => ["id" => $id, "note" => reset($item)]];
});
$result = $prices->zip($notes)->map(function ($item) {
// Feel free to call `toArray()` here if you don't want a Collection.
return collect($item)->mapWithKeys(function ($a) { return $a; });
});
Below is the $result (called using dd()).
Illuminate\Support\Collection {#1886 ▼
#items: array:2 [▼
0 => Illuminate\Support\Collection {#1888 ▼
#items: array:3 [▼
"id" => 112802
"price" => "500000"
"note" => "note 2"
]
}
1 => Illuminate\Support\Collection {#1889 ▼
#items: array:3 [▼
"id" => 113041
"price" => "1000000"
"note" => "note 1"
]
}
]
}
It's achieved by extracting the ID so that the zip can join there, but then we need a little hack with the map and mapWithKeys in the $result.
That's just because otherwise each element in $result will still have two separate arrays for $prices and $notes.

Arrays: Join two arrays in one [duplicate]

This question already has answers here:
Merge the rows of two arrays (appending row data from one array to a row in another array)
(4 answers)
Closed 2 months ago.
I have two arrays:
$array1 =
[
0 =>
[
'data1' => value1
],
1 =>
[
'data1' => value2
]
];
$array2 =
[
0 =>
[
'data2' => value1
],
1 =>
[
'data2' => value2
]
];
Only i want create this:
$arrayFinish =
[
0 =>
[
'data1' => value1,
'data2' => value1
],
1 =>
[
'data1' => value2
'data2' => value2
]
];
I have done this:
foreach ($data1 as $key=>$val)
{
$arrayFinish[] =
[
$val,
];
foreach ($data2[$key] as $key2=>$val2)
{
array_push($arrayFinish[$key],['data2'=>$val2]);
}
}
My actually result:
array:2 [▼
0 => array:2 [▼
0 => {#1546 ▼
+"data1": "BWQHCLJCH"
}
1 => {#1547 ▼
+"data2": "00308F000825"
}
]
1 => array:2 [▼
0 => {#1548 ▼
+"data1": "OTGSAVJIU"
}
1 => {#1549 ▼
+"data2": "00308F000946"
}
]
]
I am trying to do it using PHP. I am blocked right now, i am sure that that the solution is using two loops, but i am doing any bad. If you can see my actually result is not similar to my wish result.
thank u for the help.
Thank u to all that tried to help me. I find a solution.
I am tried to clear the array
foreach ($array1 as $key=>$val)
{
$arrayFinish[$key] = $val;
foreach ($array2[$key] as $key2=>$val2)
{
array_push($arrayFinish[$key],["data2"=>$val2]);
}
}
Using a for cycle i can have access using one iteration to the information. This is not the great solution that i tried to find but working.
Best regards
if your both arrays would have same no of indexes then you can do using below code
foreach ($array1 as $key=>$val) {
$arrayFinish [] = [ $array1[$key], $array2[$key] ];
}

how to add an item to array in laravel

i have a function that it fills the one array like below :
if (isset($options[$attribute->id][$optionId])) {
foreach ($options[$attribute->id][$optionId] as $item) {
. . . .
$attributeOptionsData[] = [
'id' => $optionId,
'label' => $attributeOption->label ? $attributeOption->label : $attributeOption->admin_name,
'swatch_value' => $attribute->swatch_type == 'image' ? $attributeOption->swatch_value_url : $attributeOption->swatch_value,
'products' => $options[$attribute->id][$optionId],
'images' => $productImage ?? null,
];
dd($attributeOptionsData);
}
the result of this dd is like below :
array:1 [▼
0 => array:5 [▼
"id" => 1
"label" => "black"
"swatch_value" => "#000000"
"products" => array:1 [▶]
"images" => "product/4618/rAkC2aC3QJB6kMiAAzIGk6nUzGHxpdfIS55g3T0P.jpeg"
]
]
now what i want to do is that after the last line add some content to this array and make it like below:
array:1 [▼
0 => array:5 [▼
"id" => 1
"label" => "مشکی"
"swatch_value" => "#000000"
"products" => array:1 [▶]
"images" => "product/4618/rAkC2aC3QJB6kMiAAzIGk6nUzGHxpdfIS55g3T0P.jpeg"
"custom_field" => "some value"
]
]
on the line that i dd the array i want add the customfield to it . how can i do that thanks in advance.
the reason i dont insert like others in that i want to add the custom field in a foreach loop based on 1 field of that array
So, if you simply want to add something at the bottom of an array, just use array_push().
In your case, you would need to retrieve the whole $attributeOptionsData[] in a foreach loop and append the array to the key you're in, during that loop. Be aware that this is somehow inefficient. If you want to add a line based on a value you can retrieve in the first foreach loop, you could've just made an if-statement asking for that value and add it with array_push() afterwards.
Either way, I think this is what you're looking for:
if (isset($options[$attribute->id][$optionId])) {
foreach ($options[$attribute->id][$optionId] as $item) {
$attributeOptionsData[] = [
'id' => $optionId,
'label' => $attributeOption->label ? $attributeOption->label : $attributeOption->admin_name,
'swatch_value' => $attribute->swatch_type == 'image' ? $attributeOption->swatch_value_url : $attributeOption->swatch_value,
'products' => $options[$attribute->id][$optionId],
'images' => $productImage ?? null,
];
}
foreach($attributeOptionsData as $key=>$data){
array_push($attributeOptionsData[$key], ["custom_field" => "some value"])
}
}
$attributeOptionsData is an associative array. You can assign values to it by specifying the array $key:
$attributeOptionsData[$key] = $value;

How to loop through json data php

I'm trying to loop through JSON data in php.
array:2 [
"cart" => array:3 [
0 => array:4 [
"id" => 3
"name" => "ying"
"price" => "4000"
]
1 => array:4 [
"id" => 2
"name" => "yang"
"price" => "4000"
]
2 => array:4 [
"id" => 4
"name" => "foo"
"price" => "5000"
]
]
"total" => 13000
]
I've used the json_decode function and a foreach over the data.
foreach (json_decode($arr) as $item) {
$item['name'];
}
I want to be able to get each "cart" item and the single "total" data but I keep getting an illegal offset error when i try to call things like $item['name']
As written in json_decode doc:
Note: When TRUE, returned objects will be converted into associative arrays.
If you dont pass 2nd argument as true then it will be treated as object as below.
$arr = json_decode($arr);
$names = [];
foreach ($arr->cart as $item) {
$names[] = $item->name;
}
echo $arr->total;// this is how you will get total.
If you pass 2nd argument as true then it will be treated as associative array as below.
$names = [];
$arr = json_decode($arr, true);
foreach ($arr['cart'] as $item) {
$names[] = $item['name'];
}
echo $arr['total'];// this is how you will get total.
In your code, your data is having two main keys viz. cart and total. From which, you are trying to fetch the data of cart which I specified in my answer.

PHP array_slice or equivalent on array of arrays that are keyed by ID

I have a multi-dimensional array that is keyed by uuid's and need to slice/pop/unset an element by uuid (i.e., if I had a410463e-7fe2-4fba-8733-a812c0ee8c54 and wanted to remove that item by that uuid) so that the result is essentially the same minus the one item that was removed:
array:5 [
"5fc29794-9e08-4944-ba6d-4a5fcde5c88b" => array:3 [
"id" => "5fc29794-9e08-4944-ba6d-4a5fcde5c88b"
"name" => "fuga"
"value" => 0
]
"a410463e-7fe2-4fba-8733-a812c0ee8c54" => array:3 [
"id" => "a410463e-7fe2-4fba-8733-a812c0ee8c54"
"name" => "nihil"
"value" => 0
]
"c141d973-91fe-4227-8985-04bd0665f4a8" => array:3 [
"id" => "c141d973-91fe-4227-8985-04bd0665f4a8"
"name" => "eaque"
"value" => 0
]
"17030897-1aa9-487d-a4be-d574dd0c9d9b" => array:3 [
"id" => "17030897-1aa9-487d-a4be-d574dd0c9d9b"
"name" => "eveniet"
"value" => 3
]
"901d9f8f-573f-444f-8562-0cdf5888ba6e" => array:3 [
"id" => "901d9f8f-573f-444f-8562-0cdf5888ba6e"
"name" => "in"
"value" => 6
]
]
I know how to slice by index, but am having trouble finding resources on how this might be achieved. This is for a phpunit test. I've tried unset, but can't seem to store that in a variable or just call it in an assertion:
unset($array1[$id]);
unset($array2[$id]);
Does not persist the change.
$newUnchanged = unset($array1[$id]);
$oldUnchanged = unset($array2[$id]);
Throws syntax error, unexpected 'unset' error. Ultimately I want to assert that all of the unchanged items remained the same as prior to a single item being updated. I've also tried this ugly business which is removing a single item, but not the correct one:
$keyOne = array_search($id, array_keys($array1), true);
$oldUnchanged = array_slice($array1, $keyOne, null, true);
$keyTwo = array_search($id, array_keys($array2), true);
$newUnchanged = array_slice($array2, $keyTwo, null, true);
// Shows that the item that I wanted to slice still exists in both arrays
dd($id, $oldUnchanged, $newUnchanged);
// ^ Causes this test to fail
$this->assertEquals($oldUnchanged, $newUnchaged);
I figured out I have to clone the arrays before I can unset them
$oldUnchanged = $array1;
unset($oldUnchanged[$id]);
$newUnchanged = $array2;
unset($newUnchanged[$id]);

Categories