I have the following function to work with:
function listBrandTopics($params){
self::_getParam($params,'article_path',Wrapper::basePath().'article/');
$articles = Array();
$first_pass = true;
$count = 0;
while($result['_links']['next'] || $first_pass){
$count++;
$first_pass = false;
$result = $this->_apiCall(
Array(
'path' => '/brands/'.$params['bid'].'/articles',
'request_param' => Array(
'per_page' => '100',
'page' => $count
)
)
)->getBody();
$result = json_decode($result, true);
$articles = array_merge($articles, array_filter($result['_embedded']['entries'], array($this, '_inSupport')));
}
array_walk($articles, Array($this, '_articlesProcessor'));
$topics = $this->_topicId();
$info = Array();
foreach($articles as $article){
$topic_id = intval($article['topic_id']);
foreach($topics as $topic){
$topic_name = trim($topic['name']);
if($topic_id == $topic['id']){
$info[$topic_name]['id'] = $topic['id'];
if(!is_array($info[$topic_name]['articles'])){
$info[$topic_name]['articles'] = Array();
}
array_push($info[$topic_name]['articles'], $article);
break;
}
}
}
$params['current_brand'] = self::$brand_table[$params['bid']];
$params['the_data'] = $info;
$params['the_data_json'] = json_encode($info);
return $this->_getHtmlTemplate(self::_getParam($params,'template','brandTopics.phtml'),$params);
}
It renders a list of topics and their related articles in a support site.
However, this list of topics is not alphabetically ordered.
I know that $topic['name'] is the name of the topic, but how do I get it to return them in alphabetical order?
Thanks for the help!
Use the function ksort to order $info by key
After:
$info = Array();
foreach($articles as $article){
...
}
Add:
ksort($info);
Use simple sort($array) for alphabetically sorted array.
$this->cars = array("bmw", "audi", "opel", "ford");
sort($this->cars);
Use asort($array) (with sort_flags) if You need to keep key/value association in order.
sort - manual
asort - manual
Related
I have sample function for generate unique ids:
function generate_uuid($needed_ids_num = 1, int $random_bytes_length = 6)
{
$ids = [];
while (count($ids) < $needed_ids_num) {
$id = bin2hex(random_bytes($random_bytes_length));
if (!isset($ids[$id])) $ids[$id] = true;
}
$ids = array_keys($ids);
return $ids;
}
I have this unique ids on database:
$ids_from_database = array(
'ad5dcc895ddc',
'3d036129b5b4',
'db569298c1ea',
'f919a34b31db'
);
How can I generate a unique identifier by comparing already existing identifiers from the database?
My rewrited variant function is sample:
function generate_uuid(array $ids_from_database, int $needed_new_ids = 1, int $random_bytes_length = 6)
{
$temp = $ids;
$needed_ids_num = count($ids) + $needed_ids;
while (count($ids) < $needed_ids_num) {
$id = bin2hex(random_bytes($random_bytes_length));
if (!isset($ids[$id])) $ids[$id] = true;
}
$ids = array_keys($ids);
$result = array_diff($ids, $temp);
return [
'new_uuid' => $result,
'ids' => $ids
];
}
Why my wrote function not return result arrays in incorrect variant?
If I don't misunderstood your problem, I think your first function was OK, just need to pass the ids that you got from db in this case $ids_from_database. Just compute the difference between array with array_diff() and pass the result with unique ids and all db ids. Hope this help.
<?php
function generate_uuid(array $ids_from_database, int $needed_ids_num = 1, int $random_bytes_length = 6)
{
$temp = $ids_from_database;
$ids = [];
while (count($ids) < $needed_ids_num) {
$id = bin2hex(random_bytes($random_bytes_length));
if (!isset($ids[$id])) $ids[$id] = true;
}
$result = array_diff($ids, $temp);
return [
'new_uuid' => $result,
'ids' => $temp
];
}
$ids_from_database = array(
'ad5dcc895ddc',
'3d036129b5b4',
'db569298c1ea',
'f919a34b31db'
);
$generated_ids = generate_uuid($ids_from_database);
print '<pre>';
print_r($generated_ids);
print '</pre>';
?>
DEMO: https://eval.in/1029502
I have this general data structure:
$levels = array('country', 'state', 'city', 'location');
I have data that looks like this:
$locations = array(
1 => array('country'=>'USA', 'state'=>'New York', 'city'=>'NYC', 'location'=>'Central Park', 'count'=>123),
2 => array('country'=>'Germany', ... )
);
I want to create hierarchical arrays such as
$hierarchy = array(
'USA' => array(
'New York' => array(
'NYC' => array(
'Central Park' => 123,
),
),
),
'Germany' => array(...),
);
Generally I would just create it like this:
$final = array();
foreach ($locations as $L) {
$final[$L['country']][$L['state']][$L['city']][$L['location']] = $L['count'];
}
However, it turns out that the initial array $levels is dynamic and can change in values and length So I cannot hard-code the levels into that last line, and I do not know how many elements there are. So the $levels array might look like this:
$levels = array('country', 'state');
Or
$levels = array('country', 'state', 'location');
The values will always exist in the data to be processed, but there might be more elements in the processed data than in the levels array. I want the final array to only contain the values that are in the $levels array, no matter what additional values are in the original data.
How can I use the array $levels as a guidance to dynamically create the $final array?
I thought I could just build the string $final[$L['country']][$L['state']][$L['city']][$L['location']] with implode() and then run eval() on it, but is there are a better way?
Here's my implementation. You can try it out here:
$locations = array(
1 => array('country'=>'USA', 'state'=>'New York', 'city'=>'NYC', 'location'=>'Central Park', 'count'=>123),
2 => array('country'=>'Germany', 'state'=>'Blah', 'city'=>'NY', 'location'=>'Testing', 'count'=>54),
);
$hierarchy = array();
$levels = array_reverse(
array('country', 'state', 'city', 'location')
);
$lastLevel = 'count';
foreach ( $locations as $L )
{
$array = $L[$lastLevel];
foreach ( $levels as $level )
{
$array = array($L[$level] => $array);
}
$hierarchy = array_merge_recursive($hierarchy, $array);
}
print_r($hierarchy);
Cool question. A simple approach:
$output = []; //will hold what you want
foreach($locations as $loc){
$str_to_eval='$output';
for($i=0;$i<count($levels);$i++) $str_to_eval .= "[\$loc[\$levels[$i]]]";
$str_to_eval .= "=\$loc['count'];";
eval($str_to_eval); //will build the array for this location
}
Live demo
If your dataset always in fixed structure, you might just loop it
$data[] = [country=>usa, state=>ny, city=>...]
to
foreach ($data as $row) {
$result[][$row[country]][$row[state]][$row[city]] = ...
}
In case your data is dynamic and the levels of nested array is also dynamic, then the following is an idea:
/* convert from [a, b, c, d, ...] to [a][b][...] = ... */
function nested_array($rows, $level = 1) {
$data = array();
$keys = array_slice(array_keys($rows[0]), 0, $level);
foreach ($rows as $r) {
$ref = &$data[$r[$keys[0]]];
foreach ($keys as $j => $k) {
if ($j) {
$ref = &$ref[$r[$k]];
}
unset($r[$k]);
}
$ref = count($r) > 1 ? $r : reset($r);
}
return $data;
}
try this:
<?php
$locations = [
['country'=>'USA', 'state'=>'New York', 'city'=>'NYC', 'location'=>'Central Park', 'street'=>'7th Ave', 'count'=>123],
['country'=>'USA', 'state'=>'Maryland', 'city'=>'Baltimore', 'location'=>'Harbor', 'count'=>24],
['country'=>'USA', 'state'=>'Michigan', 'city'=>'Lansing', 'location'=>'Midtown', 'building'=>'H2B', 'count'=>7],
['country'=>'France', 'state'=>'Sud', 'city'=>'Marseille', 'location'=>'Centre Ville', 'count'=>12],
];
$nk = array();
foreach($locations as $l) {
$jsonstr = json_encode($l);
preg_match_all('/"[a-z]+?":/',$jsonstr,$e);
$narr = array();
foreach($e[0] as $k => $v) {
if($k == 0 ) {
$narr[] = '';
} else {
$narr[] = ":{";
}
}
$narr[count($e[0]) -1] = ":" ;
$narr[] = "";
$e[0][] = ",";
$jsonstr = str_replace($e[0],$narr,$jsonstr).str_repeat("}",count($narr)-3);
$nk [] = $ko =json_decode($jsonstr,TRUE);
}
print_r($nk);
Database have three field:
here Name conatin contry state and city name
id,name,parentid
Pass the contry result to array to below function:
$data['contry']=$this->db->get('contry')->result_array();
$return['result']=$this->ordered_menu( $data['contry'],0);
echo "<pre>";
print_r ($return['result']);
echo "</pre>";
Create Function as below:
function ordered_menu($array,$parent_id = 0)
{
$temp_array = array();
foreach($array as $element)
{
if($element['parent_id']==$parent_id)
{
$element['subs'] = $this->ordered_menu($array,$element['id']);
$temp_array[] = $element;
}
}
return $temp_array;
}
// Get all categories
$query = "SELECT name FROM bolt_taxonomy WHERE taxonomytype = :taxonomytype AND contenttype = :contenttype";
$map = array(
':taxonomytype' => 'categories',
':contenttype' => 'news',
);
$categories = $this->app['db']->fetchAssoc($query, $map);
$response = $this->app->json(array('categories' => $categories));
return $response;
Returns:
{
"categories": {
"name": "life"
}
}
Which is just the first entry that matches the above condition on the bolt_taxonomy table. How can I get it to return the whole list of categories?
This is now solved by using fetchAll:
// Get the category
$query = "SELECT name FROM bolt_taxonomy WHERE taxonomytype = 'categories' AND contenttype = 'news'";
$categories = $this->app['db']->query($query);
$result = $categories->fetchAll();
$response = $this->app->json(array('categories' => $result));
return $response;
You need to populate using while or foreach loop.
$categories = $this->app['db']->fetchAssoc($query, $map);
foreach($categories as $category) {
$result[] = $category;
}
$response = $this->app->json($result);
echo $response;
return $response;
Hi all' I have a page into PHP where I retrieve XML data from a server and I want to store this data into an array.
This is my code:
foreach ($xml->DATA as $entry){
foreach ($entry->HOTEL_DATA as $entry2){
$id = (string)$entry2->attributes()->HOTEL_CODE;
$hotel_array2 = array();
$hotel_array2['id'] = $entry2->ID;
$hotel_array2['name'] = utf8_decode($entry2->HOTEL_NAME);
$i=0;
foreach($entry2->ROOM_DATA as $room){
$room_array = array();
$room_array['id'] = (string)$room->attributes()->CCHARGES_CODE;
$hotel_array2['rooms'][$i] = array($room_array);
$i++;
}
array_push($hotel_array, $hotel_array2);
}
}
In this mode I have the array hotel_array which all hotel with rooms.
The problem is that: into my XML I can have multiple hotel with same ID (the same hotel) with same information but different rooms.
If I have an hotel that I have already inserted into my hotel_array I don't want to insert a new array inside it but I only want to take its rooms array and insert into the exisiting hotel.
Example now my situation is that:
hotel_array{
[0]{
id = 1,
name = 'test'
rooms{
id = 1
}
}
[0]{
id = 2,
name = 'test2'
rooms{
id = 100
}
}
[0]{
id = 1,
name = 'test'
rooms{
id = 30
}
}
}
I'd like to have this result instead:
hotel_array{
[0]{
id = 1,
name = 'test'
rooms{
[0]{
id = 1
}
[1]{
id = 30
}
}
}
[0]{
id = 2,
name = 'test2'
rooms{
id = 100
}
}
}
How to create an array like this?
Thanks
first thing is it helps to keep the hotel id as the index on hotel_array when your creating it.
foreach ($xml->DATA as $entry){
foreach ($entry->HOTEL_DATA as $entry2){
$id = (string)$entry2->attributes()->HOTEL_CODE;
$hotel_array2 = array();
$hotel_array2['id'] = $entry2->ID;
$hotel_array2['name'] = utf8_decode($entry2->HOTEL_NAME);
$i=0;
foreach($entry2->ROOM_DATA as $room){
$room_array = array();
$room_array['id'] = (string)$room->attributes()->CCHARGES_CODE;
$hotel_array2['rooms'][$i] = array($room_array);
$i++;
}
if (!isset($hotel_array[$hotel_array2['id']])) {
$hotel_array[$hotel_array2['id']] = $hotel_array2;
} else {
$hotel_array[$hotel_array2['id']]['rooms'] = array_merge($hotel_array[$hotel_array2['id']]['rooms'], $hotel_array2['rooms']);
}
}
}
Whilst this is the similar answer to DevZer0 (+1), there is also quite a bit that can be done to simplify your workings... there is no need to use array_merge for one, or be specific about $i within your rooms array.
$hotels = array();
foreach ($xml->DATA as $entry){
foreach ($entry->HOTEL_DATA as $entry2){
$id = (string) $entry2->attributes()->HOTEL_CODE;
if ( empty($hotels[$id]) ) {
$hotels[$id] = array(
'id' => $id,
'name' => utf8_decode($entry2->HOTEL_NAME),
'rooms' => array(),
);
}
foreach($entry2->ROOM_DATA as $room){
$hotels[$id]['rooms'][] = array(
'id' => (string) $room->attributes()->CCHARGES_CODE;
);
}
}
}
Just in case it helps...
And this :)
$hotel_array = array();
foreach ($xml->DATA as $entry)
{
foreach ($entry->HOTEL_DATA as $entry2)
{
$hotel_code = (string) $entry2->attributes()->HOTEL_CODE;
if (false === isset($hotel_array[$hotel_code]))
{
$hotel = array(
'id' => $entry2->ID,
'code' => $hotel_code,
'name' => utf8_decode($entry2->HOTEL_NAME)
);
foreach($entry2->ROOM_DATA as $room)
{
$hotel['rooms'][] = array(
'id' => (string)$room->attributes()->CCHARGES_CODE,
);
}
$hotel_array[$hotel_code] = $hotel;
}
}
}
I have a table
Which I want show recursively like below picture
I am using a recursive function in php
function reccall($cat_id)
{
global $no,$recArray;
$sql = "SELECT a.*
FROM cat_master
WHERE
parent_id = $cat_id
ORDER BY
id ASC
";
$result = mysql_query($sql) or die("Could not fetech Recursively");
while($row = mysql_fetch_object($result))
{
$recArray[$no]['value'] = mysql_real_escape_string($row->value);
$recArray[$no]['id'] = $row->id;
++$no;
reccall($row->id);
}
return $recArray;
}
but I am not able to generate a structured array like how the order is not the picture. A simple array is created all the time. Can anyone help me with creating the structured array like the order shown above.
<?
// I identified this function separately because it is performed only once, for preparing data
// It's collect an array of all parents in the correct order for each id
function dest($array) {
foreach($array as $key=>$value) {
if($value['pid']==0) continue;
$pid = $key;
$array[$key]['dest'] = array();
while ( $pid = $array[$pid]['pid'] ) {
if($key == $pid) exit("this tree is broken");
$array[$key]['dest'][] = $pid;
}
}
return $array;
}
// Recursive function that puts the items in the correct tree. removes the parameter dest.
function tree($array) {
foreach($array as $key=>$value) {
if( is_array($value['dest']) && !empty($value['dest']) ) {
$pid = array_pop($value['dest']);
if( empty($value['dest']) ) unset($value['dest']);
$array[$pid]['childrens'][$key] = $value;
$array[$pid]['childrens'] = tree($array[$pid]['childrens']);
unset($array[$key]);
}
}
return $array;
}
$array = array(
1 => array(
'title'=>'q',
'pid'=>0,
),
2 => array(
'title'=>'w',
'pid'=>1,
),
3 => array(
'title'=>'e',
'pid'=>0,
),
4 => array(
'title'=>'r',
'pid'=>2,
),
5 => array(
'title'=>'t',
'pid'=>1,
),
);
$tree = tree( dest($array) );
echo '<pre>';
print_r($array);
print_r($tree);
?>
By the way, I should note that these arrays are not very useful. Better to use the result of the function dest().
use this function instead of your function and your problem will be solved I hope
function reccall($cat_id)
{
$sql = "SELECT a.*
FROM cat_master
WHERE
parent_id = $cat_id
ORDER BY
id ASC
";
$result = mysql_query($sql) or die("Could not fetech Recursively");
while($row = mysql_fetch_object($result))
{
$recArray[$no]['main']['value'] = mysql_real_escape_string($row->value);
$recArray[$no]['main']['id'] = $row->id;
$recArray[$no]['child'] = reccall($row->id);
++$no;
}
return $recArray;
}