I have these array but I wanted it to echo an array only for the "watch" category and wanted to store the selected array in a PHP variable, I have to try to search the web to find the solution but no success.
$arr = [
'status' => 1,
'msg' => [
'total_records' => 5,
'total_pages' => 1,
'page_number' => 1,
'per_page' => 100,
'return_count' => 5,
'page_result' => [
0 => array
(
'items' => 200052001,
'code' => 501,
'category' => 'watch',
'price' => 50,
'stock' => 1,
),
1 => array
(
'items' => 200052001,
'code' => 401,
'category' => 'shirt',
'price' =>3,
'stock' => 1,
),
2 => array
(
'items' => 200052001,
'code' => 172758801,
'category' => 'watch',
'price' => 200,
'stock' => 1,
),
],
],
'errcode' => 0,
];
This should do the trick.
$watch_array = array();
foreach($arr["msg"]["page_result"] AS $k => $item) {
if($item["category"] == "watch") {
$watch_array[] = $item;
}
}
You now have an array containing only the watch.
To display its content, use:
print_r($watch_array);
Demo Link.
Check this search function for your requirement. Its completely dynamic along with recursive nature.
function search($array, $key, $value)
{
$results = [];
if (is_array($array)) {
if (isset($array[$key]) && $array[$key] == $value) {
$results[] = $array;
}
foreach ($array as $subarray) {
$results = array_merge($results, search($subarray, $key, $value));
}
}
return $results;
}
$temp = search($arr, "category", "watch");
Source.
Related
I have data im getting from mongodb to arrays and I want to work on the return data to split it by date and some other value , this is what I got so far and I need some help with the results
<?php
$stats=array(
array("source"=>501,"status"=>"answered","dest"=>"100","date"=>"2022-17-01"),
array("source"=>501,"status"=>"noAnswer","dest"=>"120","date"=>"2022-17-01"),
array("source"=>501,"status"=>"answered","dest"=>"100","date"=>"2022-18-01"),
array("source"=>502,"status"=>"answered","dest"=>"120","date"=>"2022-17-01"),
array("source"=>502,"status"=>"answered","dest"=>"130","date"=>"2022-17-01"),
array("source"=>502,"status"=>"answered","dest"=>"110","date"=>"2022-18-01")
);
$new1 = array();
$answer = 0;
$noanswer = 0;
$lastsrc = '';
$lastdate = '';
$dest=0;
foreach ($stats as $new) {
$src = $new['source'];
$date = $new['date'];
if ( $lastsrc == $src && $lastdate == $date ) {
$dest++;
if($new['status'] == 'answered'){ $answer++; }
if($new['status'] == 'noanswer'){ $noanswer++;}
$new1[] = array('source' => $src,
'date' => $date,
'ans' => $answer,
'nonans' => $noanswer,
'dest' => $dest );
} else if ( $lastsrc == $src && $lastdate != $date ) {
$dest++;
if($new['status'] == 'answered'){ $answer++;}
if($new['status'] == 'noanswer'){ $noanswer++;}
$new1[] = array('source' => $src,
'date' => $date,
'ans' => $answer,
'nonans' => $noanswer,
'dest' => $dest );
} else {
$dest++;
if($new['status'] == 'answered'){ $answer++; }
if($new['status'] == 'noanswer'){ $noanswer++;}
$new1[] = array('source' => $src,
'date' => $date,
'ans' => $answer,
'nonans' => $noanswer,
'dest' => $dest );
$lastsrc = $src;
$lastdate = $date;
}
}
print_r($new1);
?>
what im trying to achieve is splitting the Data by date and by source as well, so if in foreach loop I found same source and same date then I modify the array instead of create new array, if its the opposite then create new array
the result im trying to get is :
array("source"=>501,"ans"=>"1","noans" => 0,"dest"=>1,"date"=>"2022-17-01"),
array("source"=>501,"ans"=>"1","noAnswer" => 1,"dest"=>2,"date"=>"2022-18-01"),
array("source"=>502,"ans"=>"2","noans" => 0,"dest"=>2,"date"=>"2022-17-01"),
array("source"=>502,"ans"=>"1","noans" => 0,"dest"=>1,"date"=>"2022-18-01")
im not sure if its the right way ,any help will be very appreciated thanks
<?php
$stats = [
[ 'source' => 501, 'status' => 'answered', 'dest' => '100', 'date' => '2022-17-01' ],
[ 'source' => 501, 'status' => 'noAnswer', 'dest' => '120', 'date' => '2022-17-01' ],
[ 'source' => 501, 'status' => 'answered', 'dest' => '100', 'date' => '2022-18-01' ],
[ 'source' => 502, 'status' => 'answered', 'dest' => '120', 'date' => '2022-17-01' ],
[ 'source' => 502, 'status' => 'answered', 'dest' => '130', 'date' => '2022-17-01' ],
[ 'source' => 502, 'status' => 'answered', 'dest' => '110', 'date' => '2022-18-01' ]
];
$result = [];
foreach ($stats as $stat) {
$source = $stat['source'];
$date = $stat['date'];
$closure = static fn($item) => $item['source'] === $source && $item['date'] === $date;
$found = array_filter($result, $closure);
if (count($found) === 0) {
$list = array_filter($stats, $closure);
$list = array_map(static fn($item) => [ 'status' => $item['status'], 'dest' => $item['dest'] ], $list);
$result[] = [
'source' => $source,
'date' => $date,
'answered' => count(array_filter(array_column($list, 'status'), static fn($item) => $item === 'answered')),
'noAnswer' => count(array_filter(array_column($list, 'status'), static fn($item) => $item === 'noAnswer')),
'dest' => count(array_column($list, 'dest')),
];
}
}
print_r($result);
Create a composite key from the fields you want to sort by and use an associative array. (A single level in the array makes sorting/merging as well as extracting the values(array_values()) afterwards easy) Then you only need to iterate over $stats and $result once each.
$result = [];
foreach($stats as $stat) {
$key = $stat['source'].'_'.$stat['date'];
if (!array_key_exists($key, $result)) {
$result[$key] = ['answered' => 0, 'noAnswer' => 0] + $stat;
}
$result[$key][$stat['status']]++;
$result[$key]['dest'][$stat['dest']] = 1;
}
$result = array_map( // Transform "destinations key store" to count
function($item) {
$item['dest'] = count($item['dest']); return $item;
},
$result
);
print_r(array_values($result));
['source' => 501, 'status' => answered, 'dest' => 2, 'date' => 2022-17-01, 'answered' => 1, 'noAnswer' => 1],
['source' => 501, 'status' => answered, 'dest' => 1, 'date' => 2022-18-01, 'answered' => 1, 'noAnswer' => 0],
['source' => 502, 'status' => answered, 'dest' => 2, 'date' => 2022-17-01, 'answered' => 2, 'noAnswer' => 0],
['source' => 502, 'status' => answered, 'dest' => 1, 'date' => 2022-18-01, 'answered' => 1, 'noAnswer' => 0]
I would like to detect same records and then change quantity of the one record and delete the others. For example, given the following array:
'Cart' => [
(int) 0 => [
'size' => '38',
'code' => '5',
'qn' => (int) 1
],
(int) 1 => [
'size' => '37',
'code' => '5',
'qn' => (int) 1
],
(int) 2 => [
'size' => '37',
'code' => '5',
'qn' => (int) 1
]
],
i would like to print:
'Cart' => [
(int) 0 => [
'size' => '38',
'code' => '5',
'qn' => (int) 1
],
(int) 1 => [
'size' => '37',
'code' => '5',
'qn' => (int) 2
]
],
It looks to me that you're trying to sum quantities (qn) on duplicate sizes (size) and codes (code). One way to achieve this is by looping through the array containing the cart items and building out a new array. I suggest reading about PHP arrays and array_key_exists to learn more as they're used below:
<?php
$arr = [
['size' => '38', 'code' => 5, 'qn' => 1],
['size' => '37', 'code' => 5, 'qn' => 1],
['size' => '37', 'code' => 5, 'qn' => 1],
['size' => '37', 'code' => 4, 'qn' => 1],
];
$newArr = [];
foreach ($arr as $value) {
$key = $value['size'] . ':' . $value['code'];
if (array_key_exists($key, $newArr)) {
$newArr[$key]['qn'] += $value['qn'];
continue;
}
$newArr[$key] = $value;
}
// Resets keys
$newArr = array_values($newArr);
print_r($newArr);
I dont know it is enough for your problem, but try function array_unique
Iterate your array and use array_diff on each subarray.
If the returned array doesn't contain neither size nor code, add the two qn
The function array_unique() works for single dimension array. To find unique elements from multi-dimension array, we need to do a little modification.
Try this:
$array = array_map("serialize", $array);
$output = array_map("unserialize", array_unique($array));
If you want to follow another approach, use this as a reference: Create multidimensional array unique
Please go through following code.
$result = [
0=> ['size' => '38',
'code' => '5',
'qn' => 1
],
1=> ['size' => '37',
'code' => '5',
'qn' => 1
],
2=> ['size' => '37',
'code' => '5',
'qn' => 1
]
];
$finalArr = [];
foreach($result as $k => $v) {
$flag = 0;
foreach($finalArr as $kc => $vc){
if($v['size']==$vc['size'] && $v['code']==$vc['code']){
$flag = 1;
$finalArr[$kc]['qn'] = $finalArr[$kc]['qn'] + 1;
break;
}
}
if($flag==0){
$finalArr[] =
[
'size' => $v['size'],
'code' => $v['code'],
'qn' => 1
];
}
}
echo "<pre>";
print_r($finalArr);
The code is tested against your question and i have explained the code. This gives you solution for any number of arrays and with similar array elements with quantity(qn) incremented as you wanted:
<?php
//Compare the 1st and 2nd array
//Compare the 2st and 3rd array
// and so on
function compare($arr1 = array(), $arr2 = array()) {
$result = array_diff($arr1, $arr2);
return $result;
}
$cart = array(
0 => array('size' => 38, 'code' => 5, 'qn' => 1),
1 => array('size' => 37, 'code' => 5, 'qn' => 1),
2 => array('size' => 37, 'code' => 5, 'qn' => 1),
);
$j = 1;
$cart_total_count = count($cart);//Gives the count of your cart
$final_cart = array();//Final array with qn incremented
for($i=0;$i<$cart_total_count; $i++) {
if (!empty($cart[$i+1])) {//If 2nd array is not present then stop the comparision
if (empty(compare($cart[$i], $cart[$i+1]))){
$j++;
$cart[$i]['qn'] = $j;
$final_cart = $cart[$i];
}
}
}var_dump($final_cart);
//Output
//1. If 2 array are same
//array(3) { ["size"]=> int(37) ["code"]=> int(5) ["qn"]=> int(2) }
//2. If no array are same
//array(0) { }?>
I have an array with the following format:
$array = Array(
Array('id' => 77, 'title' => 'title'),
Array('id' => 43, 'title' => 'title2'),
Array('id' => null, 'title' => 'title3'),
Array('id' => null, 'title' => null),
);
This array is populated dynamically, this is just an example. Also, i have a second array with the format:
$searchingArray = Array('43', '5');
The main idea is to search if values from $searchingArray are in $array and if not exists then added. My function is:
function addId($id, $ignoreIfFound=false) {
foreach ($array as $values) {
if ($values['id'] and $values['id'] == $id) {
if (!$ignoreIfFound) {
$array[] = Array('id' => $id, 'title' => 'test5');
break;
}
else{
// do nothing
}
}else{
$array[] = Array('id' => $id, 'title' => 'test5');
break;
}
}
}
foreach ($searchingArray as $id) {
$this->addId($id, true);
}
For given example the result should be:
$array = Array(
Array('id' => 77, 'title' => 'title'),
Array('id' => 43, 'title' => 'title2'),
Array('id' => null, 'title' => 'title3'),
Array('id' => null, 'title' => null),
Array('id' => 5, 'title' => 'test5'),
);
Can you tell me what it is wrong with my code?
This should work for you:
First extract the id column out of your array with array_column(). After this simply loop through your search array and check with in_array() if they id already exists or not. If not simply add it to the array.
$ids = array_column($array, "id");
foreach($searchingArray as $search) {
if(!in_array($search, $ids)) {
$array[] = ["id" => $search, "title" => "title" . $search];
}
}
How to recursively remap children to nodes? I tried writing recursive function, but it only runs one iteration. Array map - http://php.net/manual/en/function.array-map.php would only run for single dimension
I'm using nested sets model https://github.com/etrepat/baum#getting-started Input is generated by dumping all hierarchy
$array = Category::where('name', '=', 'All')->first()->getDescendantsAndSelf()->toHierarchy()->toArray();
/* Input */
$array = array(
'category_id' => 0,
'children' => array(
array(
'category_id' => 1,
'children' => array(
'category_id' => 2,
'children' => array(
'category_id' => 3,
)
)
),
array(
'category_id' => 4,
'children' => array(
'category_id' => 5,
'children' => array(
'category_id' => 6,
)
)
)
)
);
Output should be
/*
$array = array(
'category_id' => 0,
'nodes' => array(
array(
'category_id' => 1,
'nodes' => array(
'category_id' => 2,
'nodes' => array(
'category_id' => 3,
)
)
),
array(
'category_id' => 4,
'nodes' => array(
'category_id' => 5,
'nodes' => array(
'category_id' => 6,
)
)
)
)
);*/
function remap($items){
if(!empty($items['children'])){
$items['nodes'] = $items['children'];
unset($items['children']);
return remap($items['nodes']);
}
else{
return $items;
}
}
print_r(remap($array));
A bit complicated couse , childrens content variates by depth
function remap(array &$items){
if(array_key_exists('children',$items)){
$items['nodes'] = $items['children'];
unset($items['children']);
if(array_key_exists('children',$items['nodes'])){
$items['nodes']['nodes'] = $items['nodes']['children'];
unset($items['nodes']['children']);
}
foreach ($items['nodes'] as &$x) {
if (is_array($x)) {
remap($x);
}
}
}
else{
return $items;
}
}
remap($array);
print_r($array);
This function will change the children keys to nodes.
function remap($items) {
$result = array();
foreach ($items as $key => $value) {
if ($key == 'children') {
$result['nodes'] = remap($value);
} else {
$result[$key] = $value;
}
}
return $result;
}
$new_array = remap($array);
After your comment, though, it seems like it would be easier to create an accessor that maps children to nodes in your Eloquent model and use that in the select that gets your collection.
I have array:
$adm_menu_old = array (
array(
'id' => 1,
'name' => 'Test1',
),
array(
'id' => 3,
'name' => 'Test3',
'childrens' => array(
array(
'id' => 31,
'name' => 'Test31',
),
array(
'id' => 32,
'name' => 'Test32',
'childrens' => array(
array(
'id' => 321,
'name' => 'Test321',
),
),
)
),
array(
'id' => 4,
'name' => 'Test4',
),
);
Say i know id value.
I need get path with all parents of this id.
For example i need get path to this element: id=321
i need get array with key name values:
array('Test3','Test32','Test321')
how should look like recursive function?
Try this function:
function getNames($id, $arr) {
$result = array();
foreach($arr as $key => $val) {
if(is_array($val)) {
if($val["id"] == $id) {
$result[] = $val["name"];
} elseif(!empty($val["childrens"]) && is_array($val["childrens"])) {
$sub_res = getNames($id, $val["childrens"]);
if(count($sub_res) > 0) {
$result[] = $val["name"];
$result = array_merge($result, $sub_res);
}
}
}
}
return $result;
}