Laravel save multiple records - php

I've got an array within arrays and would like to add something to it.
$options = $request->options;
foreach ($options as $option) {
$option['poll_id'] = $this->id;
}
dd($options);
But for some reason it does not add to the array.
So I receive this:
array:1 [
0 => array:1 [
"name" => "testtest"
]
]
But I would expect this:
array:1 [
0 => array:1 [
"name" => "testtest",
"poll_id" => 1
]
]

You're not changing $options so foreach is destroying $option with each iteration. Try something like this instead:
$options = [];
foreach ($request->options as $key => $value) {
$options[$key]['poll_id'] = $this->id;
}

You should do it using the $key attribute on arrays
// Suppose your $request->options is like:
$options = [
0 => [
"name" => "testtest"
]
];
foreach ($options as $key => $option) {
$options[$key]['poll_id'] = 3; // Changing variable - $options here.
}
and it should work!
// $options would be like:
array:1 [▼
0 => array:2 [▼
"name" => "testtest"
"poll_id" => 3
]
]

Related

How to create a 2 dimensional array from an associative array in php

i need to convert a associative array to a 2 dimensional array in php, the origin array is as followed
array:7 [▼
"data" => "data"
"id_1553539135251" => "<p>nsmn</p>"
"about" => "about"
"id_1553539141598" => "<p>uiu</p>"
my code
$data = $request->all();
$json = array();
foreach($data as $key => $value){
if(strpos($key, 'id') !== false){
$json[$key]['content'] = $value;
}
}
i need the output of the following for each to be
array:3 [▼
"id_1553539135251" => array:1 [▼
"content" => "<p>nsmn</p>"
"data" => "data"
]
"id_1553539141598" => array:1 [▼
"content" => "<p>uiu</p>"
"about" => "about"
]
]
but my code outputs
array:3 [▼
"id_1553539135251" => array:1 [▼
"content" => "<p>nsmn</p>"
]
"id_1553539138029" => array:1 [▼
"content" => "<p>jjkjk</p>"
]
"id_1553539141598" => array:1 [▼
"content" => "<p>uiu</p>"
]
]
guidance on how to achieve the desired output is appreciated.
<?php
$test=array(
array(
"data" => "data",
"id_1553539135251" => "<p>nsmn</p>",
"about" => "about",
"id_1553539141598" => "<p>uiu</p>"
),
);
$output=array();
foreach($test as $item){
$i=0;
$tt='';
foreach($item as $k=>$v){
if(strpos($k, 'id') !== false){
$output[$k]=array(
'content'=>$item[$k],
'header'=>$tt,
);
}else{
$tt=$v;
}
}
}
print_r($output);

Laravel get group of arrays

I have code below and result is like:
array:2 [▼
0 => array:1 [▼
"CPU" => "AMD a5"
]
1 => array:1 [▼
"CPU" => "AMD a9"
]
]
I want to group them in same array like
CPU => [
"0" => "AMD a5",
"1" => "AMD a9"
]
Code
$category = Category::where('slug', $slug)->where('status', '=', 'active')->first();
$products = $category->products;
foreach ($products as $product) {
foreach($product->attributes as $attribut){
$attributes[] = [$attribut->group->title => $attribut->title];
}
}
What should I change?
If you want a bit of a more scalable solution where you might have multiple attribute types, the following may help:
$attributes = [
[
'CPU' => 'AMD A5'
],
[
'CPU' => 'AMD A9'
],
[
'GFX' => 'AMD'
]
];
return collect($attributes)
->groupBy(function($item) {
return key($item);
})
->map(function($item) {
return array_flatten($item);
})
->toArray();
The output of the above will be:
array:2 [▼
"CPU" => array:2 [▼
0 => "AMD A5"
1 => "AMD A9"
]
"GFX" => array:1 [▼
0 => "AMD"
]
]
Here's an example you can play with.
if your $attribut->group->title is "CPU" and your $attribut->title is "AMD a5"
then you can use this
foreach ($products as $product) {
foreach($product->attributes as $attribut){
$attributes[$attribut->group->title][] = $attribut->title;
}
}
from #mozammil answer if you still wanna do using foreach
$attributes =
[
[
'CPU' => 'AMD A5'
],
[
'CPU' => 'AMD A9'
],
[
'GFX' => 'AMD'
]
];
$data = [];
foreach ($attributes as $titles){
foreach ($titles as $title=> $row){
$data[$title][] = $row;
}
}
You can try collection methods here is an example.
$keyed = $collection->map(function ($item,$key) {
return [[$key] => $item['CPU']];
});
For more information
https://laravel.com/docs/5.7/collections#method-map
Use array_column to get one column of an array.
$category = Category::where('slug', $slug)->where('status', '=', 'active')->first();
$products = $category->products;
$cpu = array_column($products, "CPU");
This will return an array as your expected result.
https://3v4l.org/UYPhK
This requires PHP 7 since in older versions array_column can't handle objects

How map array of array to single assoc array?

I have:
array:2 [
0 => array:1 [
"FNAME" => "nullable|string"
]
1 => array:1 [
"LNAME" => "nullable|string"
]
]
And I try to get:
array:1 [
"key" => "value"
]
I try map it, but has problem
<?php
$array = [
[
"FNAME" => "nullable|string",
],
[
"LNAME" => "nullable|string",
]
];
$newArray = [];
foreach ($array as $item) {
foreach ($item as $key => $value) {
$newArray[$key] = $value;
}
}
print_r($newArray);
Will output:
Array
(
[FNAME] => nullable|string
[LNAME] => nullable|string
)
Two simple ways:
print_r(array_merge(...$arr));
// if `...` is not available (php < 5.6), then:
print_r(call_user_func_array('array_merge', $arr))

How to navigate back up in a multidimensional array after finding the appropriate child?

I have an array that looks like this:
RecursiveArrayIterator {#605 ▼
+"xs:schema": array:2 [▼
"value" => array:1 [▼
"xs:element" => array:2 [▼
"value" => array:1 [▼
"xs:complexType" => array:2 [▼
"value" => array:2 [▼
"xs:sequence" => array:2 [▼
"value" => array:1 [▼
"xs:element" => array:3 [▼
0 => array:2 [▼
"value" => array:1 [▼
"xs:simpleType" => array:2 [▼
"value" => array:1 [▼
"xs:restriction" => array:2 [▼
"value" => array:1 [▼
"xs:maxLength" => array:1 [▼
"attributes" => array:1 [▼
"value" => "40"
]
]
]
"attributes" => array:1 [▶]
]
]
"attributes" => []
]
]
"attributes" => array:1 [▼
"name" => "title"
]
]
1 => array:2 [▶]
2 => array:2 [▶]
]
]
"attributes" => []
]
"xs:attribute" => array:2 [▶]
]
"attributes" => []
]
]
"attributes" => array:1 [▼
"name" => "book"
]
]
]
"attributes" => []
]
}
I need to access the xs:maxLength attribute, so in order to that that, I'm using the following method:
private function findRestrictions(array $haystack, $needle)
{
$iterator = new \RecursiveArrayIterator($haystack);
$recursive = new \RecursiveIteratorIterator(
$iterator,
\RecursiveIteratorIterator::SELF_FIRST
);
foreach ($recursive as $key => $value)
{
if ($key === $needle)
{
return (int)$value['attributes']['value'];
}
}
}
$maxLength = findRestrictions($array, 'xs:maxLength');
So that gives me back 40, just like expected. Anyway, my issue is that I need to know to which element this limit belongs to, which is mentioned in xs:element[0]['attributes']['name'] and I'm uncertain on how to reach there to grab the information I need, based on the match for xs:maxLength.
Well I have programmed a pretty good solution I think, this time it is tested.
My sample array:
$array = [
"we" =>
["are" => [
"lorem" => [
"gone" => "away",
"my" => "friend"
],
"never" => "abcd",
"any" => [
"btc" => "abc",
"help" => [
"mqf" => "bmx"
]
]
]
],
"fancy" => [
"lorem" => [
"gone" => "away",
"my" => "friend"
],
"never" => "abcd",
"any" => [
"btc" => "abc",
"help" => [
"mqf" => "bmx",
"abc" => 13
]
]
],
"beer" => "bar",
"helpful" => [
"meta" => "column",
"gamma" => [
"lorem" => [
"gone" => "mad",
"my" => "drink"
],
"never" => "abcd",
"any" => [
"btc" => "abc",
"help" => [
"mqf" => "bmx",
"abc" => "alot"
]
]
]
],
"elements" => [
0 => 88,
1 => 99
]
];
My solution:
function array_find_value_return_parent($array,$needle,$parentkey) {
$iterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator($array),
RecursiveIteratorIterator::SELF_FIRST);
foreach($iterator as $key => $value) {
if($value === $needle) {
for ($i = $iterator->getDepth() - 1; $i >= 0; $i--) {
if($iterator->getSubIterator($i)->key() === $parentkey) {
return $iterator->getSubIterator($i)->current();
}
}
}
}
}
function array_find_key_return_value($array,$findkey) {
$iterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator($array),
RecursiveIteratorIterator::SELF_FIRST);
foreach($iterator as $key => $value) {
if($findkey === $key) {
return $iterator->current();
}
}
}
My test:
$findvalue = "alot";
$findparentkey = "gamma";
$findreturnkey = "gone";
echo array_find_key_return_value(array_find_value_return_parent($array,$findvalue,$findparentkey),$findreturnkey);
Output: mad
For your case it means that you might do the following:
$findvalue = "40";
$findparentkey = "xs:element";
$findreturnkey = "name";
echo array_find_key_return_value(array_find_value_return_parent($array,$findvalue,$findparentkey),$findreturnkey);
Expected output: title
Right?
I do not know your original data structure, so I just converted your data to a PHP array. You can use $aks = new ArrayKeySearcher($data, 'xs:maxLength'); to find the key you want. And you can make the search more complex to satisfy your requirement.
However, if you are using something like XML, it is highly recommended to use XML-based solutions, like XPath query (eg: http://php.net/manual/en/domxpath.query.php, http://php.net/manual/en/simplexmlelement.xpath.php). These methods are easier to use, faster and more accurate.
<?php
$data = [
"xs:schema"=> [
"value" => [
"xs:element" => [
"value" => [
"xs:complexType" => [
"value" => [
"xs:sequence" => [
"value" => [
"xs:element" => [
0 => [
"value" => [
"xs:simpleType" => [
"value" => [
"xs:restriction" => [
"value" => [
"xs:maxLength" => [
"attributes" => [
"value" => "40"
]
]
],
"attributes" => []
]
],
"attributes" => []
]
],
"attributes" => [
"name" => "title"
]
],
1 => [],
2 => [],
]
],
"attributes" => []
],
"xs:attribute" => []
],
"attributes" => []
]
],
"attributes" => [
"name" => "book"
]
]
],
"attributes" => []
]
];
class ArrayKeySearcher
{
public $data;
public $path;
public $value;
public function __construct($data, $key)
{
$this->data = $data;
$this->findKeyPath($data, $key);
}
private function findKeyPath($data, $key)
{
foreach ($data as $k => $v) {
$this->path[] = $k;
if ($key === $k) {
$this->value = $v;
return;
}
$this->findKeyPath($v, $key);
if (!is_null($this->value))
return;
array_pop($this->path);
}
}
public function arrayReverseSearch($a, $k, $pos = null)
{
$count = count($a);
$i = ($pos === null) ? ($count - 1) : $pos;
for(; $i >= 0; $i--) {
if($a[$i] === $k)
return $i;
}
return $i;
}
public function getValueByPath($path)
{
$v = $this->data;
foreach($path as $k) {
if(isset($v[$k]))
$v = $v[$k];
}
return $v;
}
}
$aks = new ArrayKeySearcher($data, 'xs:maxLength');
echo 'path: ' . json_encode($aks->path) . PHP_EOL;
echo 'value: ' . json_encode($aks->value) . PHP_EOL;
$p = $aks->path;
$pos = $aks->arrayReverseSearch($p, 'xs:simpleType');
$pos = $aks->arrayReverseSearch($p, 'value', $pos);
$p = array_slice($p, 0, $pos);
$parent = $aks->getValueByPath($p);
echo 'parent path: ' . json_encode($p) . PHP_EOL;
echo 'parent attributes: ' . json_encode($parent['attributes']) . PHP_EOL;
Output:
path: ["xs:schema","value","xs:element","value","xs:complexType","value","xs:sequence","value","xs:element",0,"value","xs:simpleType","value","xs:restriction","value","xs:maxLength"]
value: {"attributes":{"value":"40"}}
parent path: ["xs:schema","value","xs:element","value","xs:complexType","value","xs:sequence","value","xs:element",0]
parent attributes: {"name":"title"}

How to build an array in recursion?

I have the following structure array:
array:6 [▼
"593a4331b25f428814000035" => array:8 [▶]
"593a4331b25f428814000036" => array:8 [▶]
"593a4331b25f428814000037" => array:8 [▶]
"593a4331b25f428814000038" => array:8 [▼
"_id" => MongoId {#238 ▶}
"object_id" => "593a4331b25f428814000034"
"parameter_id" => "59398f5ab25f424016000029"
"value" => "1"
"children" => []
"parent_id" => "593a4331b25f428814000037"
"type" => "2"
"prefix" => "object"
]
"593a4331b25f428814000039" => array:8 [▶]
"593a4331b25f42881400003a" => array:8 [▶]
]
As you can see 3-th element of array has parent 593a4331b25f428814000037, where identificator is element in the same array.
How to put this element 593a4331b25f428814000038 inside parent in children?
In result I need to get:
"593a4331b25f428814000037" => array:8 [▼
"_id" => MongoId {#238 ▶}
"object_id" => "593a4331b25f428814000034"
"parameter_id" => "59398f5ab25f424016000029"
"value" => "1"
"children" => [ 0 => array("_id" => MongoId {#238 ▶}
"object_id" => "593a4331b25f428814000034"
"parameter_id" => "59398f5ab25f424016000029"
"value" => "1"
"children" => []
"parent_id" => "593a4331b25f428814000037"
"type" => "2"
"prefix" => "object")]
"parent_id" => "593a4331b25f428814000037"
"type" => "2"
"prefix" => "object"
]
I tried this way:
public function recursion($data){
foreach ($data as $k => $value) {
if (is_array($value['children']) && count($value['children']) > 0) {
$list[$k] = $value;
$list[$k]["children"] = $this->getChildren($all, $value['children']);
} else {
$list[$k] = $value;
}
}
return $list;
}
private function getChildren($all, $childs)
{
$list = [];
foreach ($childs as $k => $child) {
if (is_array($all[$child]['children'])) {
$tmpArray = $all[$child];
$tmpArray['children'] = $this->getChildren($all, $all[$child]['children']);
} else {
$tmpArray = $all[$child];
}
$list[] = $tmpArray;
}
return $list;
}
But it works incorrect
You can use array_reduce like:
$array = array_reduce($myArray, function ($carry, $item) {
if (empty($item['parent_id'])) {
$carry[$item['object_id']] = $item;
} else {
$carry[$item['parent_id']]['children'][] = $item;
}
return $carry;
}, []);
var_dump($array);
In this example I supposed the parent_id is empty for those items which doesn't belong to a another item. You can change that with isset in case there is no parent_id key

Categories