array, getting title and data of top levels - php

I currently have an issue with a block of code where a simple change gives me one or the other attribute I'm looking for but not both. I can get the title or the value of the first three levels in this array but not both.
This:
array_walk($promo, function ($e) use (&$results) {
$results['ID']['name']['type'][] = [
'ATT' => $e['ATT'],
'ATT2' => $e['ATT2'],
'ATV' => $e['ATV']
];
});
This gives structure with titles like:
ID
name
type: array(
123,
abc,
blue
)
array_walk($promo, function ($e) use (&$results) {
$ID = &$e['ID'];
$name = &$e['name'];
$type = &$e['type'];
$results[$ID][$name][$type][] = [
'ATT' => $e['ATT'],
'ATT2' => $e['ATT2'],
'ATV' => $e['ATV']
];
});
This gives structure with data but no titles
ID:26
NewList
Task_list: array(
123,
abc,
blue
)
How can I refactor this to give me a list with the first three levels having title and data like so:
ID:26
name:NewList
type:Task_list: array(
123,
abc,
blue
)

Try to modify the array_walk like this :
array_walk($promo, function ($e) use (&$results) {
$ID = &$e['ID'];
$name = &$e['name'];
$type = &$e['type'];
$results['ID'][$ID]['name'][$name]['type'][$type][] = [
'ATT' => $e['ATT'],
'ATT2' => $e['ATT2'],
'ATV' => $e['ATV']
];
});

Related

How can I build an multi-dimentional array from a wpdb query return?

I am trying to build a multi-dimensional array from a query return and ran into a problem. Here is a sanitized snippet similar to what I am trying to do. My problem is building the sub array. Any suggestions to get my desired output? I used JSON so it would be more obvious. I can parse an array or JSON.
<?php
// this is my query
global $wpdb;
$locationData = $wpdb->get_results("SELECT
locations.locationID,
locations.location_name,
locations.city,
locations.state,
locations.products,
locations.type,
locations.sku
");
// which returns something like
// [locationID] [location_name] [city] [state] [products] [type] [sku]
// 001 Tulsa Outlet Tulsa OK cakes chocolate 3763
// 001 Tulsa Outlet Tulsa OK cakes lemon 3765
// 001 Tulsa Outlet Tulsa OK sodas coke 4983
// 001 Tulsa Outlet Tulsa OK sodas sprite 4950
// and so on..
// I build an array to be consumed by another function that I created in my plugin:
foreach( $locationData as $key => $location ) {
$output[$row['locationID']] = array(
'locationID' => $row['locationID'],
'location_name' => $row['location_name'],
'products' => array(
// this is where my previous attempts broke down
)
);
$output[$key]['city'] = $location->city;
$output[$key]['state'] = $location->state;
}
// and the $output I need would look like this:
{
"locations" : [
{
"locationID" : "001",
"location_name" : "Tulsa Outlet",
"products" : {
"cakes" : {
"chocolate" : "3763",
"lemon" : "3765"
},
"sodas" : {
"coke" : "4983",
"sprite" : "4950"
}
},
"city" : "Tulsa",
"state" : "ok"
}
]
}
?>
These should help:
$output = [];
foreach ($locationData as $location) {
$locId = $location->locationID;
if (empty($output[$locId])) {
$output[$locId] = [
'locationID' => $location->locationID,
'location_name' => $location->location_name,
'city' => $location->city,
'state' => $location->state,
'products' => [],
];
}
$productType = $location->products;
if (empty($output[$locId]['products'][$productType])) {
$output[$locId]['products'][$productType] = [];
}
$output[$locId]['products'][$productType][$location->type] = $location->sku;
}
Not really sure what you use - $row or $location, so changed everything to $location.
To reindex $output to 0-index array, use array_values.

Add PHP string value to JSON array

I got this:
$arr = json_decode($arr, TRUE);
while($row){
// $arr[] = ['id' => '8', 'name' => 'mickey'];
$test = $row->TCI_LIBELLE;
$arr[] = ['id' => $row->TCI_ID, 'name' => $row->TCI_LIBELLE];
$i +=1;
$row = $reqCentreInteret->fetch(PDO::FETCH_OBJ);
$json = json_encode($arr);
If you don't understand I'm trying to put values I get from a Select SQL query into a JSON array.
The problem is that it does't work like I want.
Indeed it works with my id because in my database it's an int value, but it does't work for the name because it is a varchar value
This is what i want to obtain :
[{"id":"8","name":"mickey"},{"id":"8","name":"mickey"}]
And here 'mickey' will be replaced by the value of my php string that will be initialized by my sql query
I already tried to solve my problem using
'name' => '" .$row->TCI_LIBELLE."'
But it does't work
How can I pass string value (or other type) to my JSON array?
I'm using PHP and JSON to send value from MySQL to an Android app.
arr[] = adds a new row to the array, i.e. a new top-level element.
You probably want to add your data to the existing element
Let's say your arr initially is something like
[ 'property1' => 'value1',
'property2' => 'value2'
...]
when you're doing
arr[] = ['id'=> 8,'name' => 'mickey']
your array will now contain 2 top level elements and look like
[[ 'property1' => 'value1',
'property2' => 'value2'
...
],
[ 'id' => 8,
'name' => 'mickey'
]
]
you may want to do this instead
arr['id'] = $row->TCI_ID;
arr['name'] = $row->TCI_LIBELLE;
then your arr will look like this:
[ 'property1' => 'value1',
'property2' => 'value2'
'id' => 8
'name' => 'mickey'
...
]
Finally this is what is had to do
$stmt = $db->query("SELECT TCI_ID AS id, TCI_LIBELLE AS nom FROM
OSO_DEV.T_CENTRE_INTERET");
echo json_encode($stmt->fetchAll(PDO:: FETCH_ASSOC),JSON_UNESCAPED_UNICODE);

Array sort menu

I have the following array to show menu's based on the order the user specified.
The array is as follows:
$menuArray = [
'Main Street' => [
['/index.php', 'Home'],
['/city.php', $cityData[$user->city][0]],
['/travel.php', 'Travel'],
['/bank.php', 'Bank'],
['/inventory.php', 'Inventory'],
['/dailies.php', 'Dailies'],
],
'Activities' => [
(!$my->hospital) ? ['/hospital.php', 'Hospital'] : [],
(!$my->hospital && !$my->prison) ? ['/crime.php', 'Crime'] : [],
['/missions.php', 'Missions'],
['/achievements.php', 'Achievements'],
],
'Services' => [
['/hospital.php', 'Hospital'],
['/prison.php', 'Prison'],
['/search.php', 'Search'],
],
'Account' => [
['/edit_account.php', 'Edit Account'],
['/notepad.php', 'Notepad'],
['/logout.php', 'Logout'],
]
];
I have a column menu_order stored in the database, which has a default value of 0,1,2,3,4, but this can change per user as they will be able to change their menu to their likes.
What I'd like to achieve:
0 => Main Street
1 => Activities
2 => Services
3 => Account
4 => Communication
To get the menu order, I do
$menuOrder = explode(',', $user->menu_order);
But I'm not sure how to handle the foreach for displaying the menu.
Here's one way to do it -- use replacement rather than a sorting algorithm.
Code: (Demo)
$menuArray = [
'Main Street' => [],
'Activities' => [],
'Services' => [],
'Account' => []
];
$lookup = [
0 => 'Main Street',
1 => 'Activities',
2 => 'Services',
3 => 'Account',
4 => 'Communication'
];
$customsort = '4,2,1,3,0';
$keys = array_flip(explode(',', $customsort)); convert string to keyed array
//var_export($keys);
$ordered_keys = array_flip(array_replace($keys, $lookup)); // apply $lookup values to keys, then invert key-value relationship
//var_export($ordered_keys);
$filtered_keys = array_intersect_key($ordered_keys, $menuArray); // remove items not on the current menu ('Communication" in this case)
//var_export($filtered_keys);
$final = array_replace($filtered_keys, $menuArray); // apply menu data to ordered&filtered keys
var_export($final);
Output:
array (
'Services' =>
array (
),
'Activities' =>
array (
),
'Account' =>
array (
),
'Main Street' =>
array (
),
)
And here's another way using uksort() and a spaceship operator:
$ordered_keys = array_flip(array_values(array_replace(array_flip(explode(',', $customsort)), $lookup)));
uksort($menuArray, function($a, $b) use ($ordered_keys) {
return $ordered_keys[$a] <=> $ordered_keys[$b];
});
var_export($menuArray);
As a consequence of how your are storing your custom sort order, most of the code involved is merely to set up the "map"/"lookup" data.
You could try something like this to produce the menu:
function display_menu($menus, $m) {
if (!isset($menus[$m])) return;
echo "<ul>";
foreach ($menus[$m] as $item) {
if (!count($item)) continue;
echo "<li>{$item[1]}\n";
}
echo "</ul>";
}
$menuMap = array(0 => 'Main Street',
1 => 'Activities',
2 => 'Services',
3 => 'Account',
4 => 'Communication');
$menuOrder = explode(',', $user->menu_order);
foreach ($menuOrder as $menuIndex) {
$thisMenu = $menuMap[$menuIndex];
display_menu($menuArray, $thisMenu);
}
Small demo on 3v4l.org

check if value exist in each array multidimensional array

i hava multidimensional array
<?php
$data = array(
array(
'name'=>'ahmed',
'job'=>'engineer',
'age'=>25,
'hobbies' => array('drawing','swimming','reading'),
'skills' => array('coding','fasting learning','teaching')
),
array(
'name'=>'Sara',
'job'=>'designer',
'age'=>19,
'skills'=>array('fast learning')
) ,
array(
'name'=>'Ali',
'age'=>25,
'city'=>'cairo'
),
array(
'name'=>'Hossam',
'job'=>'accountant',
'age'=>25,
'city'=>'zagazig'
),
array(
'name'=>'Esraa',
'job'=>'Designer',
'age'=>23,
'city'=>'zagazig',
'hobbies' => array('writing','reading'),
'skills' => array('coding','teaching')
),
);
i want count Arrays where city = "zagazig" or "cairo"
and echo Array Values
Example :
There is [ 1 ] people of City => [ cairo ] :
---------------- Result -----------------------
Name => Ali
Age => 25
City => cairo
if City !exist echo Values
Example :
*---------------- Invaild Data -------------
----------------------- First ---------------
Name => Sara
Job => designer
Age => 19
Skill => fast learning
----------------- Second ----------------
Name => ahmed
Job => engineer
Age => 25
-------------------- Hobbies ----------------
drawing
swimming
reading
-------------------- Skills ----------------
coding
fasting learning
teaching
but i don't know how to loop Multidimensional Array
Given that this is just a raw array, a simple if with foreach should suffice.
First, if the criteria is to get certain entries using city, just use a stripos to search;
$search_string = 'zagazig';
$results = array();
foreach($data as $value) {
if(
!empty($value['city']) &&
(stripos($value['city'], $search_string) !== false)
) {
$results[] = $value;
}
}
This checks if the entry has a city index, then just pushes that array inside a container $result. After gathering the results, just loop it like any normal array:
if(!empty($results)) {
echo 'Number of results: ' , count($results), '<br/> Result <hr/>';
foreach($results as $r) {
echo "
Name: {$r['name']}
Job: {$r['job']}
Age: {$r['age']} <br/>
";
echo !empty($r['hobbies']) ? '<br/>Hobbies: <br/>' . implode('<br/>', $r['hobbies']) : '';
}
}
Output
Of course you can use a <table> tag if you want, this is just an ugly example.
If you like something a little bit different, you can also use array_filter:
Here's an example of it (this also includes some searching inside hobbies and skills):
$search_string = 'coding';
$criteria = 'skills';
$results = array_filter($data, function($e) use ($search_string, $criteria) {
return (
!empty($e[$criteria]) &&
(!is_array($e[$criteria])
? (strpos($e[$criteria], $search_string) !== false)
: (in_array($search_string, $e[$criteria]))
)
);
});
Output
Use php foreach() like:
foreach (array_expression as $value)
{
statement
}
Foreach Documentation

how to set selected multiple combo box based on array

I have two sets of array ,first array contains all categories called "all", and second array contains selected categories called "selected", I want to populate this concept to multiple combo box,
$all = [
0 => [
'id'=>1,
'name' => 'news'
],
1 => [
'id'=>2,
'name' => 'tips'
],
2 => [
'id'=>3,
'name' => 'trick'
],
3 => [
'id'=>4,
'name' => 'review'
]
];
$selected = [
0 => [
'id'=>2,
'name' => 'trick'
],
1 => [
'id'=>4,
'name' => 'review'
],
];
I've try to do foreach in foreach , but i have duplicated data when show in combo box, i want to have all data from "all" shown with selected data from "selected".
i just solved my problem in deferent way , first i add default pair of key and value "sel"=>0 in "all" array set, then i loop trough array "all" and array "sel" to get similar value and when it match change sel key to 1 ,this code for further explanation
public static function compare($sel,$all){
// add sel key with default value = 0
foreach($all as $k=>$v){
$all[$k]['sel'] = 0;
}
foreach($all as $k=>$v){
foreach($sel as $k2=>$v2){
// when match change sel to 1
if($v['id'] == $v2['id']){
$all[$k]['sel'] = 1;
}
}
}
return $all;
}
final result :
$all = [
0 => [
'id'=>1,
'name' => 'news',
'sel' => 0
],
1 => [
'id'=>2,
'name' => 'tips',
'sel' => 0
],
2 => [
'id'=>3,
'name' => 'trick',
'sel' => 1
],
3 => [
'id'=>4,
'name' => 'review',
'sel' => 1
]
];
just add if condition when $all['sel'] = 1 they should be selected, thanks all :D
You can get the intersection of both arrays with array_uintersect and a custom callback function (compare).
function compare($a, $b){
if($a['id'] == $b['id']){
return 0;
}
return 1;
}
$res = array_uintersect($selected, $all,"compare");
print_r($res);
>Array ( [0] => Array ( [id] => 2 [name] => trick ) [1] => Array ( [id] => 4 [name] => review ) )
After that you only need to loop through the final array and set the corresponding check boxes.
If you want to compare by name just create another callback function.
function compare2($a, $b){
if($a['name'] == $b['name']){
return 0;
}
return 1;
}
The duplicates are caused by the inner for loop continuing to create select elements even after it has found a selected element. You can avoid having an inner loop and using php's in_array() function to check if $all is in $selected like this:
$x = '';
foreach($all as $a){
if(in_array($a, $selected)){
$x .= '<option selected>'.$a['id'].'Selected </option>';
}else{
$x .= '<option>'.$a['id'].'Not selected </option>';
}
}
echo $x;
Note that in_array will check all values of the elements, so for example element with id 2 but different name will appear as not selected. You may want to change both names to tips. I hope that helps.

Categories