Count images from dirs and show less on top - php

I am using this code to display the total files in different directories, all good but for example cats=50 then dogs=30 and fish=10. how can I make something so that I get fish on top then dogs and finally cats..
function scan_dir($path){
$ite=new RecursiveDirectoryIterator($path);
$nbfiles=0;
foreach (new RecursiveIteratorIterator($ite) as $filename=>$cur) {
$nbfiles++;
}
if($nbfiles > 2) $nbfiles = $nbfiles - 2;
return $nbfiles;
}
$dogs = scan_dir('/home/dogs/');
$cats = scan_dir('/home/cats/');
$fish = scan_dir('/home/fish/');
<table border="1">
<tr><td><b>Animal</b></></></td><td><b>Total Files</b></></></td></tr>
<tr><td>Dogs</td><td><?=$dogs?></td></tr>
<tr><td>Cats</td><td><?=$cats?></td></tr>
<tr><td>Fish</td><td><?=$fish?></td></tr>
</table>

Quick and dirty:
$dogs = scan_dir('/home/dogs/');
$cats = scan_dir('/home/cats/');
$fish = scan_dir('/home/fish/');
$arr = array("Dogs" => $dogs, "Cats" => $cats, "Fish" => $fish);
asort($arr);
echo '<table border="1">';
echo "<tr><td><b>Animal</b></></></td><td><b>Total Files</b></></></td></tr>";
foreach ($arr as $key=>$value) {
echo "<tr><td>$key</td><td>$value</td></tr>";
}
echo "</table>";
With a working example.

$array = array($dogs => 'dogs', $cats => 'cats', $fish => 'fish');
ksort($array); //sorts array the way you want
This should work.

<?php
function scan_dir($path){
$count = 0;
$it = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS);
foreach (new RecursiveIteratorIterator($it) as $dummy) {
++$count;
}
return $count;
}
$animals = array(
'Dogs' => '/home/dogs/',
'Cats' => '/home/cats/',
'Fish' => '/home/fish/',
);
foreach ($animals as $animal => $path) {
$animals[$animal] = scan_dir($path);
}
arsort($animals);
?>
<table border="1">
<tr><td><b>Animal</b></td><td><b>Total Files</b></td></tr>
<?php foreach ($animals as $animal => $count): ?>
<tr><td><?=$animal?></td><td><?=$count?></td></tr>
<?php endforeach; ?>
</table>

Related

While loop and match records in one foreach with another

Here is the code that I will be using:
$wp_query = new WP_Query([
'post_type' => 'office',
'post_status' => 'any',
'posts_per_page' => -1,
]);
$offices = [];
if (count($wp_query->posts) > 0) {
$offices = $wp_query->posts;
}
$settings['started'] = time();
foreach ($offices as $office) {
$key['_office_id'] = get_post_meta($office->ID, '_office_id', true);
}
foreach ($records as $record) {
$record_key = strtoupper(str_replace(' ', '',
trim($record->location_id) . trim($record->business_unit)));
}
$key outputs the following:
Array
(
[_office_id] => ATLANTAFHUSA
)
Array
(
[_office_id] => AUSTINFHUSA
)
$record_key outputs the following:
ATLANTAFHUSA
AUSTINFHUSA
Here is what I'm trying to achieve .. I want to create a while loop inside the records foreach that will look at the $record_key and if there is a match with $key['_office_id'] to go ahead and echo that out.
What I attempted inside the $records foreach:
while ($record_key == $key['_office_id']) {
if ($record_key == $key['_office_id']) {
echo $record_key . " has a matching record.";
} else {
echo $record_key . " does not have a matching record.";
}
}
$keys = [];
// Store all office ids
foreach ($offices as $office) {
$keys[] = get_post_meta($office->ID, '_office_id', true);
}
foreach ($records as $record) {
$record_key = strtoupper(str_replace(' ', '',
trim($record->location_id) . trim($record->business_unit)));
// Check if current `record_key` is in `$keys` array
if (in_array($record_key, $keys)) {
echo 'Record key is in keys';
} else {
// do something else
}
}

Creating a dynamic hierarchical array in PHP

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;
}

merge array with itself from foreach loop

I have foreach loop like:
foreach($attributes as $key => $value)
{
$option[] =["$value->name"=>"$value->value"]; //it is like ["color"=>"red"]
}
I want to merge $option[0], $option[1] and so on.... How to merge that ?
I tried:
for($i=1;$i<$count;$i++)
{
$option = array_merge($option[0],$option[$i]);
}
If you want a merged version, try this (you need only 1 loop):
$merged_options = array();
foreach($attributes as $key => $value)
{
$option[] =["$value->name" => "$value->value"];
$merged_options[$value->name] = $value->value;
}
This code should hopefully loop through each of your current arrays and reconstruct it to a multi-dimensional array.
foreach($attr as $k=>$v):
$temp = array();
$i = 0;
while(count($k) != $i):
array_push($temp, $k[$i] => $v[$i]);
$i++;
endwhile;
array_push($attr, $temp);
endforeach;
Hope it helped.
Why not you use something like this:
foreach($attributes as $key => $value)
{
$option[$value->name] =$value->value;
}

Transform numeric array in associative in order to access it from html template

Alright, my data gets stored in a file using the same pattern:
id|title|content
I created a function which explodes the entries by the delimiter '|' into an array.
function get_entries(){
$retAr = array();
$data = file_get_contents("db/entries.log");
$lines = explode("\n", $data); //create array separate by new line
foreach($lines as $line){
$retAr[] = explode('|', $line );
}
return array_reverse( $retAr );
}
Accessable in html:
<?php foreach(get_entries() as $entry): ?>
<a class='title'><?php echo $entry[1];?></a>
<p class='content'><?php echo $entry[2];?></p>
<?php endforeach; ?>
Okay, it works so far but I want to access the data using an associative array pretty much like this.
<?php foreach(transform_to_assoc(get_entries()) as $entry): ?>
<a class='title'><?php echo $entry['title'];?></a>
<p class='content'><?php echo $entry['content'];?></p>
<?php endforeach; ?>
Related function I've written:
function transform_to_assoc($num_array){
$keys = array('id', 'title', 'content');
$assoc = array();
foreach ($num_array as $data) {
foreach ($keys as $key) {
$assoc[$key] = $data;
}
}
return $assoc;
}
Unfortunately, it does not work. Maybe I got something wrong, but I'm sure my approach was the right one. Help would be appreciated.
That should do what you want:
function transform_to_assoc($num_array){
$keys = array('id', 'title', 'content');
$assoc = array();
foreach ($keys as $k=>$key) {
$assoc[$key] = $num_array[$k];
}
return $assoc;
}
Edit:
To use this for a multi dimensional array do the following:
$arr = array(
array(0, 'test heading 1', 'test content 1'),
array(1, 'test heading 1', 'test content 1'),
);
$newArray = array();
foreach($arr as $a) {
$newArray[] = transform_to_assoc($a);
}
function transform_to_assoc($num_array){
$keys = array('id', 'title', 'content');
$assoc = array();
foreach ($keys as $k=>$key) {
$assoc[$key] = $num_array[$k];
}
return $assoc;
}
You could use the list construct. Just exchange the first foreach loop with this:
foreach($lines as $i => $line){
list($retAr[$i]['id'], $retAr[$i]['title'], $retAr[$i]['content']) = explode('|', $line );
}

PHP How to count same words in foreach loop

I have this result inside my foreach loop:
Tonsilitis
Tonsilitis
Laryngitis
Rhinosinusitis Akut
Rhinosinusitis Akut
Rhinosinusitis Akut
Common Cold
Common Cold
Common Cold
Rhinitis Alergi
This is my script:
foreach ($results as $data) :
$final = $data->nama_diagnosis . '<br>';
echo $final;
endforeach;
My question is, how can i count the same word in my loop or outside the loop. Can i do that? give me the solution please. As a result i want to count them like this:
Tonsilitis = 2
Laryngitis = 1
Rhinosinusitis Akut = 3
Common Cold = 3
Rhinitis Alergi = 1
Or maybe i can filter the same word so i get only the most words, like Rhinosinusitis Akut and Common Cold. Please help me.
Thanks
You can try something like this, iterating through array with foreach loop and using a ternary operator with isset to safely assign and increment each occurrence:
$count = array();
foreach ($results as $result)
isset($count[$data]) ? $count[$data]++ : $count[$data] = 1;
Example
In foreach loop save words and their count into array, then make another loop and write the amounts.
<?php
$results = array(
array('nama_diagnosis' => 'Tonsilitis'),
array('nama_diagnosis' => 'Tonsilitis'),
array('nama_diagnosis' => 'Laryngitis'),
array('nama_diagnosis' => 'Rhinosinusitis Akut'),
array('nama_diagnosis' => 'Rhinosinusitis Akut'),
array('nama_diagnosis' => 'Rhinosinusitis Akut'),
array('nama_diagnosis' => 'Common Cold'),
array('nama_diagnosis' => 'Common Cold'),
array('nama_diagnosis' => 'Common Cold'),
array('nama_diagnosis' => 'Rhinitis Alergi')
);
$res = array();
foreach ($results as $words) { // changed $word to $words
foreach ($words as $word) { // this foreach added
if (isset($res[$word])) {
$res[$word] += 1;
} else {
$res[$word] = 1;
}
} // end of nested foreach which was added
}
foreach ($res as $word => $count) {
echo $word . ' (' . $count . ')<br>';
}
/*
output:
Tonsilitis (2)
Laryngitis (1)
Rhinosinusitis Akut (3)
Common Cold (3)
Rhinitis Alergi (1)
*/
?>
Try with -
$counts = array();
foreach ($results as $data) :
$final = $data->nama_diagnosis . '<br>';
if (array_key_exists($data->nama_diagnosis, $counts)) {
$counts[$data->nama_diagnosis] += 1;
} else {
$count[$data->nama_diagnosis] = 1;
}
endforeach;
foreach ($counts as $key => $val) {
echo $key.' = '.$val;
}
This should work for you:
<?php
$results = array("Tonsilitis", "Tonsilitis", "Laryngitis", "Rhinosinusitis Akut", "Rhinosinusitis Akut", "Rhinosinusitis Akut", "Common Cold", "Common Cold", "Common Cold", "Rhinitis Alergi");
$counter = array();
foreach ($results as $data):
if(in_array($data->nama_diagnosis, array_flip($counter)))
$counter[$data->nama_diagnosis]++;
else
$counter[$data->nama_diagnosis] = 1;
endforeach;
foreach ($counter as $key => $data)
echo $key . " = " . $data . "<br />";
?>
Output:
Tonsilitis = 2
Laryngitis = 1
Rhinosinusitis Akut = 3
Common Cold = 3
Rhinitis Alergi = 1

Categories