Group array results in Alphabetic order PHP (continued) - php

I'm sorry for the uncreative title.
I'm trying to group my array alphabetically. The accepted answer in this question (by Hugo Delsing) helped greatly to my task, but I still want to take things a bit further...
here's my current code:
$records = ['7th Trick', 'Jukebox', 'Dynamyte', '3rd Planet'];
$lastChar = '';
sort($records, SORT_STRING | SORT_FLAG_CASE);
foreach($records as $val) {
$char = strtolower($val[0]);
if ($char !== $lastChar) {
if ($lastChar !== '') echo "</ul>";
echo "<h2>".strtoupper($char)."</h2><ul>";
$lastChar = $char;
}
echo '<li>'.$val.'</li>';
}
echo "</ul>";
I want to make things so that non-alphabetic items would get grouped together instead of separated individually.
example:
"7th Trick" and "3rd Planet" get grouped together as non-alphabetic instead of displayed separately under "7" and "3" category respectively.
any idea how to do it?

You can just add one line to your existing code to accomplish this.
$char = strtolower($val[0]);
// Convert $char to one value if it isn't a letter
if (!ctype_alpha($char)) $char = 'Non-alphabetic';
if ($char !== $lastChar) {
The rest of it should work the same.

Remove the alphas from the array and show them after printing the alphas.
<?php
$records = ['7th Trick', 'Jukebox', 'Dynamyte', '3rd Planet'];
$lastChar = '';
sort($records, SORT_STRING | SORT_FLAG_CASE);
$alpha = array();
$non_alpha = array();
foreach($records as $val) {
if (ctype_alpha($val[0])) {
$alpha[] = $val;
} else {
$non_alpha[] = $val;
}
}
foreach($alpha as $val) {
$char = strtolower($val[0]);
if ($char !== $lastChar) {
if ($lastChar !== '') echo "</ul>";
echo "<h2>".strtoupper($char)."</h2><ul>";
$lastChar = $char;
}
echo '<li>'.$val.'</li>';
}
echo "</ul>";
if (sizeof($non_alpha) > 0) {
echo "<h2>Digits</h2><ul>";
foreach ($non_alpha as $val) {
echo '<li>'.$val.'</li>';
}
echo "</ul>";
}

Related

I have code like this How to code print like this?

input name: DEVO AVIDIANTO PRATAMA
output: DAP
if the input three word , appears DAP
input name: AULIA ABRAR
output: AAB
if the input two words, appears AAB
input name: AULIA
output: AUL
  if the input one word, appears AUL
<?php
$nama = $_POST['nama'];
$arr = explode(" ", $nama);
//var_dump($arr);die;
$jum_kata = count($arr);
//echo $jum_kata;die;
$singkatan = "";
if($jum_kata == 1){
//print_r($arr);
foreach($arr as $kata)
{
echo substr($kata, 0,3);
}
}else if($jum_kata == 2) {
foreach ($arr as $kata) {
echo substr($kata,0,2);
}
}else {
foreach ($arr as $kata) {
echo substr($kata,0,1);
}
}
?>
how to correct this code :
else if($jum_kata == 2) {
foreach ($arr as $kata) {
echo substr($kata,0,2);
}
to print AAB?
As a variant of another approach. Put each next string over the previous with one step shift. And then slice the start of a resulting string
function initials($str, $length=3) {
$string = '';
foreach(explode(' ', $str) as $k=>$v) {
$string = substr($string, 0, $k) . $v;
}
return substr($string, 0, $length);
}
echo initials('DEVO AVIDIANTO PRATAMA'). "\n"; // DAP
echo initials('AULIA ABRAR'). "\n"; // AAB
echo initials('AULIA'). "\n"; // AUL
demo
You could do:
elseif ($jum_kata == 2) {
echo substr($kata[0],0,1);
echo substr($kata[1],0,2);
}
This will just get the first character of the first word, and then two characters from the next word.
You are returning two characters from each word which is why you get AUAB.

Inserting an item after specific array pattern

I would like to insert an item after a specific pattern. In my case I would like to insert x after every second a in an array. After six'th a my code does not work properly:
$array = array("a","a","a","a","a","a","b","a","a");
$out = array();
foreach ($array as $key=>$value){
$out[] = $value; // add current letter to new array
if($value=='a' && $array[$key-1]=='a' && $out[$key] !='x'){ // check if current and last letter are a
$out[] = 'x'; // if so add an x to the array
}
}
print_r($out);
Correct answer at the end
Is it that what are you looking for?
<?php
$array = array("a","a","a","a","a","a","b","a","a");
foreach ($array as $key => $value){
if ($key == 0 || $key == 1) {
$array[$key] = $value;
} elseif($array[$key-1] == 'a' && $array[$key-2] == 'a' && $array[$key] == 'a') {
$array[$key] = 'x';
} else {
$array[$key] = $value;
}
}
$count = count($array);
if ($array[$count-1] == 'a' && $array[$count-2] == 'a') {
$array[] = 'x';
}
print_r($array);
?>
If I understand correctly, after 2 a you want to put x into new array.
UPDATE
Please check now. There will be added a new element x if last two are a in array.
With exceptions, but still working:
<?php
$array = array("a","a","a","a","a","a","b","a","a");
foreach ($array as $key => $value){
if($array[$key-1] == 'a' && $array[$key-2] == 'a' && $array[$key] == 'a') {
$array[$key] = 'x';
}
}
$count = count($array);
if ($array[$count-1] == 'a' && $array[$count-2] == 'a') {
$array[] = 'x';
}
print_r($array);
?>
UPDATE - Correct code
I think code below will fit all your needs:
<?php
$arr = array("a","w","a","d","a","a","b","a","a", "w");
$arr_count = count($arr);
for ($i = 0; $i < $arr_count; $i++){
if (!empty($arr[$i+1]) && $arr[$i] == $arr[$i+1]) {
$first_half = array_slice($arr, 0, $i+2);
$second_half = array_slice($arr, $i+2, $arr_count);
if (count($second_half) > 0) {
$arr = array_merge($first_half, ["x"], $second_half);
}
}
}
$count = count($arr);
if ($arr[$count-1] == 'a' && $arr[$count-2] == 'a') {
$arr[] = 'x';
}
print_r($arr);
?>
As it was mentioned in the comment, you sure can use regular expression in this particular situation:
$pattern = '/a{2}/';
$replacement = '$0x';
$out = str_split(preg_replace(
$pattern,
$replacement,
implode('', $array)
));
Basically, we gluing the characters together (using implode) to form the string and then replacing every "aa" with "aax". After that we split string back to the array using str_split.
Here is demo.

Change case of every nth letter in a string in PHP

Locked. There are disputes about this question’s content being resolved at this time. It is not currently accepting new answers or interactions.
I am trying to write a simple program which takes every 4th letter (not character) in a string (not counting spaces) and changes the case to it's opposite (If it's in lower, change it to upper or vice versa).
What I have so far:
echo preg_replace_callback('/.{5}/', function ($matches){
return ucfirst($matches[0]);
}, $strInput);
Expected Result: "The sky is blue" should output "The Sky iS bluE"
$str = 'The sky is blue';
$strArrWithSpace = str_split ($str);
$strWithoutSpace = str_replace(" ", "", $str);
$strArrWithoutSpace = str_split ($strWithoutSpace);
$updatedStringWithoutSpace = '';
$blankPositions = array();
$j = 0;
foreach ($strArrWithSpace as $key => $char) {
if (empty(trim($char))) {
$blankPositions[] = $key - $j;
$j++;
}
}
foreach ($strArrWithoutSpace as $key => $char) {
if (($key +1) % 4 === 0) {
$updatedStringWithoutSpace .= strtoupper($char);
} else {
$updatedStringWithoutSpace .= $char;
}
}
$arrWithoutSpace = str_split($updatedStringWithoutSpace);
$finalString = '';
foreach ($arrWithoutSpace as $key => $char) {
if (in_array($key, $blankPositions)) {
$finalString .= ' ' . $char;
} else {
$finalString .= $char;
}
}
echo $finalString;
Try this:
$newStr = '';
foreach(str_split($str) as $index => $char) {
$newStr .= ($index % 2) ? strtolower($char) : strtoupper($char);
}
it capitalize every 2nd character of string
<?php
$str = "The sky is blue";
$str = str_split($str);
$nth = 4; // the nth letter you want to replace
$cnt = 0;
for ($i = 0; $i < count($str); $i++) {
if($str[$i]!=" " && $cnt!=$nth)
$cnt++;
if($cnt==$nth)
{
$cnt=0;
$str[$i] = ctype_upper($str[$i])?strtolower($str[$i]):strtoupper($str[$i]);
}
}
echo implode($str);
?>
This code satisfies all of your conditions.
Edit:
I would have used
$str = str_replace(" ","",$str);
to ignore the whitespaces in the string. But as you want them in the output as it is, so had to apply the above logic.

How to list items in alphabetical order with a heading and if no match is found display a message

My plan of action was:
Loop through an array of the alphabet
While inside of that loop, print the current letter
While inside of that loop cycle through a list of city objects stored in an array.
Check and see if the first letter of the $city->city_name property matches the current letter in the loop. If it matches, print it.
If there are no matches, print a message saying so.
This is all I can get it to display:
A
There are no results to display.
B
There are no results to display.
C
City
There are no results to display.
D
There are no results to display.
E
City
There are no results to display.
As you can see, the error displays even if there is a match. I cannot seem to figure out where the flaw in my logic is and I've searched through every question on the topic. Is there something obvious that I am missing?
Code:
<?php
function printValues($cities, $county)
{
$str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$letters = str_split($str);
$lettersMatched = FALSE;
foreach ($letters as $letter)
{
echo "<h5 class=\"letter\">".$letter."</h5><hr>";
foreach ($cities as $city)
{
if(substr($city->city_name, 0, 1) == $letter)
{
$lettersMatched = TRUE;
$result = $city->city_name;
echo "<p>".$result."</p>";
$lettersMatched = FALSE;
}
}
if (!$lettersMatched)
{
echo "<p>There are no results to display.</p>";
}
}
}
?>
You're resetting $lettersMatched to false inside the if statement. Try this:
<?php
function printValues($cities, $county)
{
$str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$letters = str_split($str);
//$lettersMatched = FALSE;
foreach ($letters as $letter)
{
echo "<h5 class=\"letter\">".$letter."</h5><hr>";
$lettersMatched = FALSE;
foreach ($cities as $city)
{
if(substr($city->city_name, 0, 1) == $letter)
{
$lettersMatched = TRUE;
$result = $city->city_name;
echo "<p>".$result."</p>";
// $lettersMatched = FALSE;
}
}
if (!$lettersMatched)
{
echo "<p>There are no results to display.</p>";
}
}
}
?>
$matches = false;
foreach(range('A', 'Z') AS $letter)
{
echo $letter . '<hr>';
foreach( $cities AS $city )
{
if( strtoupper(substr($city->city_name, 0, 1)) === $letter)
{
$matches = true;
echo "<p>" . $city->city_name . "</p>";
}
}
if(!$matches)
echo "<p>No matches here</p>";
$matches = false;
}
What you did was to set the matches to false right after you set it to true in the inner loop. So when your code reaches the condition outside the loop it will always be false.
What I did was to set the matches to false after the condition, so it will be checked again for each new letter.

Implode() array and make new line after two elements

I am looking to echo comma separated elements of an array e.g:
Element1, Element2, Element3, Element4, Element5, Element6
However, for the purposes of keeping the echoed elements neat, I might need to go to a new line after the each second element of each line e.g
Element1, Element2,
Element3, Element4,
Element5, Element6
As is I am doing:
<?php
$labels = Requisitions::getLabelNames($id);
foreach($labels as $label) {
$labels_array[] = $label['name'];
}
echo implode(' ,', $labels_array);
?>
And obviously getting:
Element1, Element2, Element3, Element4, Element5, Element6
How then do i do a newline after each second element of a line using implode() or otherwise?
<?php
$labels = array('Element1', 'Element2', 'Element3', 'Element4', 'Element5', 'Element6');
# Put them into pairs
$pairs_array = array_chunk($labels, 2);
# Use array_map with custom function
function joinTwoStrings($one_pair) {
return $one_pair[0] . ', ' . $one_pair[1];
}
$pairs_array = array_map('joinTwoStrings', $pairs_array);
echo implode(',' . PHP_EOL, $pairs_array);
You can use foreach to achive it, im pasting code for you which will give you your desired output
<?php
$labels = array("Element1", "Element2", "Element3", "Element4", "Element5","Element6");
$key = 1;
$lastkey = sizeof($labels);
foreach($labels as $value)
{
if($key%2)
{
if($key==$lastkey)
{
echo $value;
}
else
{
echo $value.",</br>";
}
}
else
{
if($key==$lastkey)
{
echo $value."</br>";
}
else
{
echo $value.",</br>";
}
}
$key++;
}
?>
untested, but something like this should work
$i = 1;
foreach($labels as $label) {
echo $label;
// add a comma if the label is not the last
if($i < count($labels)) {
echo ", ";
}
// $i%2 is 0 when $i is even
if($i%2==0) {
echo "<br>"; // or echo "\n";
}
$i++;
}
For the sake of fancy:
$labels_array=array("Element 1","Element 2","Element 3","Element 4","Element 5","Element 6");
echo implode(",\n",array_map(function($i){ // change to ",<br />" for HTML output
return implode(", ",$i);
},array_chunk($labels_array,2)));
Online demo
<?php
$labels = Requisitions::getLabelNames($id);
foreach($labels as $label) {
$labels_array[] = $label['name'];
}
for($i=0;$i<count($labels_array);$i++)
{ echo($labels_array[$i]);
if($i % 2 != 0)
{
echo("\n");
}else{echo(",");}
}
?>
$i = 1;
$str = '';
foreach($labels AS $label)
{
$str += "$label, ";
if ($i % 2 == 0)
{
$str += "\n";
}
$i++;
}
//Remove last 2 chars
$str = substr($str,0,(strlen($str)-2));
Unless you need the array for something else, this just builds the string...
<?php
$labels = Requisitions::getLabelNames($id);
$s='';
$i=0;
$l=count($labels);
foreach($labels as $label){
$s.=$label['name'];
// Append delimeter. Makes sure every second, and the last one, will be a line break
$s.=((++$i%2)&&($l!=$i))?' ,':"\n";
}
echo $s;
?>
If you do need the array for something, create it first and modify above as needed.

Categories