Sorting data in an array - php

I got an array which has 7 types of fruit:
$fruits = array(
"lemon",
"orange",
"banana",
"apple",
"cherry",
"apricot",
"Blueberry"
);
I don't know how to print out the data in a way that the outcome will like this:
<A>
Apple, Apricot <!--(Note that Apricot is followed by Apple in alphabetic order)-->
<B>
Banana
<C>
Cherry
<L>
Lemon
<O>
Orange
I am sorry that the question may be a bit difficult.
But please kindly help if you could.

I'd first use an array sorting function like sort(), and then create a loop that goes through the array and keeps track of what the first letter of the last word it output is - each time the first letter changes, output a new heading first.

Try this:
sort($fruit);
$lastLetter = null;
foreach ($fruit as $f) {
$firstLetter = substr($f, 0, 1);
if ($firstLetter != $lastLetter) {
echo "\n" . $firstLetter . "\n";
$lastLetter = $firstLetter;
}
echo $f . ", ";
}
There's some tidying up needed from that snippet, but you get the idea.

You can do this:
// make the first char of each fruit uppercase.
for($i=0;$i<count($fruits);$i++) {
$fruits[$i] = ucfirst($fruits[$i]);
}
// sort alphabetically.
sort($fruits);
// now create a hash with first letter as key and full name as value.
foreach($fruits as $fruit) {
$temp[$fruit[0]][] = $fruit;
}
// print each element in the hash.
foreach($temp as $k=>$v) {
print "<$k>\n". implode(',',$v)."\n";
}
Working example

This should do what you are looking for:
$fruits = array("lemon","orange","banana","apple","cherry","apricot","Blueberry");
//place each fruit in a new array based on its first character (UPPERCASE)
$alphaFruits = array();
foreach($fruits as $fruit) {
$firstChar = ucwords(substr($fruit,0,1));
$alphaFruits[$firstChar][] = ucwords($fruit);
}
//sort by key
ksort($alphaFruits);
//output each key followed by the fruits beginning with that letter in a order
foreach($alphaFruits as $key=>$fruits) {
sort($fruits);
echo "<{$key}>\n";
echo implode(", ", $fruits)."\n";
}

Related

How to use preg_replace in foreach loop in multidimensional array?

I'm a beginner in PHP.
My purpose is to print three sentences with a multi-dimensional array :
cats are smelly
birds are beautiful
snails are sticky
But the only sentence I'm able to print is "cats are smelly". I've tried many things. So here is the code:
<?php
$sentence = 'dogs are sweet';
$animals = array('#dogs#' => array('cats', 'birds', 'snails'),
'#sweet#' => array('smelly', 'beautiful', 'sticky'));
foreach ($animals as $key => $value)
{
foreach ($value as $subkey => $subvalue)
{
$sentence = preg_replace($key, $subvalue, $sentence);
}
}
echo $sentence . '</br>';
?>
How can I resolve this?
There are multiple layers as to why your solution doesn't work.
The sentence is only echoed once
Sentence is being replaced, so once "dogs" is replaced, it won't replace anything else because dogs isn't in the sentence anymore.
The script loops through the animals array only once.
Any item is replaced with any item (You specified you want cats to be smelly, birds to be beautiful and snails to be sticky, this means to compare index 0 of the first array with index 0 of the second array, index 1 with index 1, etc.).
I changed your script slightly to make sure it loops through the list thrice, for each time it echoes the output and the sentence is reset to it's default value so it can be changed again.
$animals = array('#dogs#' => array('cats', 'birds', 'snails'),
'#sweet#' => array('smelly', 'beautiful', 'sticky'));
for ($i = 0; $i < count(reset($animals)); $i++) {
$sentence = 'dogs are sweet';
foreach ($animals as $key => $value)
{
foreach ($value as $subkey => $subvalue)
{
if ($subkey === $i) {
$sentence = preg_replace($key, $subvalue, $sentence);
}
}
}
echo $sentence . "<br />";
}
The part count(reset($animals)) counts the value of the first element of the $animals array. So in this case array('cats', 'birds', 'snails'). The script assumes the first and the second array are always equal in size.
The if statement in the secondary foreach loop is to make sure the right element from one array is matched with the right element from the other.
I hope this helps

How to search for 2 or more matches in a single string?

I want to search for two or more words, but not able to match the exact word.
If I use some other function like stripos() I don't get the required output.
$string = "abc india ltd";
$Arr = array('xyz ab','abc india', 'pqr', 'yz lmn');
$Arr = implode('',$Arr);
if (preg_match_all("/$string/", $Arr)) {
echo '<b>'.'found'.'<font color="green">'.$string.'</font>'.'</b>';
}
or (Both Same, But want to avoid using inside a loop)
$string = "abc india ltd";
$Arr = array('xyz ab','abc india', 'pqr', 'yz lmn');
foreach ($Arr as $value) {
if (preg_match_all("/$string/", $value)) {
echo '<b>'.'found '.'<font color="green">'.$string.'</font>'.'</b>';
}
}
I think you want like this:-
<?php
$string = "abc india";
$Arr = array('xyz india','abc india', 'pqr', 'yz lmn',"xyz abc india");
foreach($Arr as $val){
$explode_string = explode(" ",$string);
$counter =0;
foreach($explode_string as $explode_str){
if(strpos($val,$explode_str) !== FALSE){
$counter +=1;
}
}
if($counter>=2){
echo $val. " have exact ".$counter. " word matches";
echo PHP_EOL;
}
}
Output:-https://eval.in/831808
Note:- check it with all possible test-cases and let us know, worked or not?
This leverages some smart array functions to keep the code block concise and avoid manually incrementing a counter:
Code: (Demo)
$input_string="abc india ltd";
$input_array=explode(' ',$input_string);
$search_array=array('xyz ab','abc india','ltd abc','yz lmn');
foreach($search_array as $search_string){
if(sizeof(array_intersect($input_array,explode(' ',$search_string)))>1){
echo "More than one word in $search_string was found in $input_string\n";
}
}
Output:
More than one word in abc india was found in abc india ltd
More than one word in ltd abc was found in abc india ltd
*note, array_intersect() generates a new array that only contains elements that exist in both provided arrays. sizeof() is an alias of count().

PHP Number of Times Word Appears

I'm trying to learn some PHP and have something I've got quite stuck on.
I'm using SOAP. Is it possible for me to match a word to what's in the array and then output a the number of times that word was displayed in the array?
I currently have this which outputs what I want to match to, but I can't seem to find a way to show how many times a word appears.
$facilities = $message->Facilities->FacilityInfo;
foreach ($facilities as $data) {
echo $data->Name."<br>";
}
Any help would be great!
As Niranjan pointed out, you can use an if statement in the loop and count specific words.
$cnt = array();
foreach ($facilities as $data) {
if ($data->Name == "Jan") $cnt++; // the best given name ever ;-)
echo $data->Name."<br>";
}
echo "Count of Jan: " . $cnt;
As an alternative, if the whole $facilities array consists of words only, you could do a more abstract approach:
$cnt = array();
$facilities = ['Jan', 'Ben', 'Jan', 'Agathe', 'Christine', 'Jan'];
foreach ($facilities as $name) {
$cnt[$name]++;
echo $name."<br>";
}
print_r($cnt);
// array("Jan" => 3, "Ben" => 1, "Agathe" => 1, "Christine" => 1);
Besides my narcisstic personality disorder (counting me a couple of times, that is ;-)), this might be a good starting point.
You can use:
<?php
$searchWord = 'search';
$message = "search search no yes maybe works";
$words = explode(" ", $message);
if (in_array($searchWord,$words)) {
$cntArray = array_count_values($words);
echo $cntArray[$searchWord] . " $searchWord word count";
}
?>

How Can I Extract the stringlength higher word in an array?

In the first time, I'm sorry for my disastrous english.
After three days trying to solve this, i give up.
Giving this array:
$names = array ( "James Walter Case", "Benjamin Wallace Pinkman", "Billy Elliot Newson" )
I have to extract the full name of the higher first stringlength word of each full name.
In this case, considering this condition Benjamin will be the higher name. Once
this name extracted, I have to print the full name.
Any ideas ? Thanks
How about this?
$names = array ( "James Walter Case", "Benjamin Wallace Pinkman", "Billy Elliot Newson" );
if (count($names) > 0)
{
$higher_score = 0;
foreach ($names as $name_key => $name_value)
{
$name_array = explode(" ", $name_value);
// echo("<br><b>name_array -></b><pre><font FACE='arial' size='-1'>"); print_r($name_array); echo("</font></pre><br>");
$first_name = $name_array[0];
// echo "first_name -> ".$first_name."<br>";
$score = strlen($first_name);
// echo "score -> ".$score."<br>";
if ($score > $higher_score)
{
$higher_score = $score;
$winner_key = $name_key; }
}
reset($names);
}
echo("longest first name is ".$names[$winner_key]." with ".$higher_score." letters.");
As said before, you can use array_map to get all the lenghts of the first strings, and then get the name based on the key of that value.
$names = array ( "James Walter Case", "Benjamin Wallace Pinkman", "Billy Elliot Newson" );
$x = array_map(
function ($a) {
$x = explode (" ", $a); // split the string
return strlen($x[0]); // get the first name
}
, $names);
$maxs = array_keys($x, max($x)); // get the max values (may have equals)
echo $names[$maxs[0]]; // get the first max
-- EDIT
Actually, there is a better way of doing this, considering this case. You can simply order the array by the lenght of the first names, and then get the first key:
usort($names,
function ($a, $b) {
$aa = explode(" ", $a); // split full name
$bb = explode(" ", $b); // split full name
if (strlen($aa[0]) > strlen($bb[0])){
return 0; // if a > b, return 0
} else {
return 1; // else return 1
}
}
);
echo $names[0]; // get top element
Allow me to provide a handmade solution.
<?php
$maxLength = 0;
$fullName = "";
$parts = array();
foreach($names as $name){
/* Exploding the name into parts.
* For instance, "James Walter Case" results in the following array :
* array("James", "Walter", "Case") */
$parts = explode(' ', $name);
if(strlen($parts[0]) > $maxLength){ // Compare first length to the maximum.
$maxLength = strlen($parts[0]);
$fullName = $name;
}
}
echo "Longest first name belongs to " . $fullName . " (" . $maxLength . " character(s))";
?>
Basically, we iterate over the array, split each name into parts (delimited by spaces), and try to find the maximum length among first parts of names ($parts[0]). This is basically a maximum search algorithm.
There may be better ways with PHP array_* functions, but well, this one gets pretty self-explanatory.
You can try something like..
$maxWordLength=0;
$maxWordIndex=null;
foreach ($names as $index=>$name){
$firstName=first(explode(' ',$name));
if (strlen($firstName)>maxWordLength){
$maxWordLength=strlen($firstName);
$maxWordIndex=$index;
}
}
if ($maxWordIndex){
echo $names[$maxWordIndex];
}

php remove duplicate words in an array

Sorry for English is not my mother language, maybe the question title is not quite good. I want to do something like this.
$str = array("Lincoln Crown","Crown Court","go holiday","house fire","John Hinton","Hinton Jailed");
here is an array, "Lincoln Crown" contain "Lincoln" and "Crown", so remove next words, which contains these 2 words, and "Crown Court(contain Crown)" has been removed.
in another case. "John Hinton" contain "John" and "Hinton", so "Hinton Jailed(contain Hinton)" has been removed. the final output should be like this:
$output = array("Lincoln Crown","go holiday","house fire","John Hinton");
for my php skill is not good, it is not simply to use array_unique() array_diff(), so open a question for help, thanks.
I think this might work :P
function cool_function($strs){
// Black list
$toExclude = array();
foreach($strs as $s){
// If it's not on blacklist, then search for it
if(!in_array($s, $toExclude)){
// Explode into blocks
foreach(explode(" ",$s) as $block){
// Search the block on array
$found = preg_grep("/" . preg_quote($block) . "/", $strs);
foreach($found as $k => $f){
if($f != $s){
// Place each found item that's different from current item into blacklist
$toExclude[$k] = $f;
}
}
}
}
}
// Unset all keys that was found
foreach($toExclude as $k => $v){
unset($strs[$k]);
}
// Return the result
return $strs;
}
$strs = array("Lincoln Crown","Crown Court","go holiday","house fire","John Hinton","Hinton Jailed");
print_r(cool_function($strs));
Dump:
Array
(
[0] => Lincoln Crown
[2] => go holiday
[3] => house fire
[4] => John Hinton
)
Seems like you would need a loop and then build a list of words in the array.
Like:
<?
// Store existing array's words; elements will compare their words to this array
// if an element's words are already in this array, the element is deleted
// else the element has its words added to this array
$arrayWords = array();
// Loop through your existing array of elements
foreach ($existingArray as $key => $phrase) {
// Get element's individual words
$words = explode(" ", $phrase);
// Assume the element will not be deleted
$keepWords = true;
// Loop through the element's words
foreach ($words as $word) {
// If one of the words is already in arrayWords (another element uses the word)
if (in_array($word, $arrayWords)) {
// Delete the element
unset($existingArray[$key]);
// Indicate we are not keeping any of the element's words
$keepWords = false;
// Stop the foreach loop
break;
}
}
// Only add the element's words to arrayWords if the entire element stays
if ($keepWords) {
$arrayWords = array_merge($arrayWords, $words);
}
}
?>
As I would do in your case:
$words = array();
foreach($str as $key =>$entry)
{
$entryWords = explode(' ', $entry);
$isDuplicated = false;
foreach($entryWords as $word)
if(in_array($word, $words))
$isDuplicated = true;
if(!$isDuplicated)
$words = array_merge($words, $entryWords);
else
unset($str[$key]);
}
var_dump($str);
Output:
array (size=4)
0 => string 'Lincoln Crown' (length=13)
2 => string 'go holiday' (length=10)
3 => string 'house fire' (length=10)
4 => string 'John Hinton' (length=11)
I can imagine quite a few techniques that can provide your desired output, but the logic that you require is poorly defined in your question. I am assuming that whole word matching is required -- so word boundaries should be used in any regex patterns. Case sensitivity isn't mentioned. I am unsure if only fully unique elements (multi-word strings) should have their words entered into the black list. I'll offer a few snippets, but choosing the appropriate technique will depend on exact logical requirements.
Demo
$output = [];
$blacklist = [];
foreach ($input as $string) {
if (!$blacklist || !preg_match('/\b(?:' . implode('|', $blacklist) . ')\b/', $string)) {
$output[] = $string;
}
foreach(explode(' ', $string) as $word) {
$blacklist[$word] = preg_quote($word);
}
}
var_export($output);
Demo
$output = [];
$blacklist = [];
foreach ($input as $string) {
$words = explode(' ', $string);
foreach ($words as $word) {
if (in_array($word, $blacklist)) {
continue 2;
}
}
array_push($blacklist, ...$words);
$output[] = $string;
}
var_export($output);
And my favorite because it performs fewest iterations in the parent loop, is more compact, and doesn't require the declaration/maintenance of a blacklist array.
Demo
$output = [];
while ($input) {
$output[] = $words = array_shift($input);
$input = preg_grep('~\b(?:\Q' . str_replace(' ', '\E|\Q', $words) . '\E)\b~', $input, PREG_GREP_INVERT);
}
var_export($output);
You can explode each string in the original array and then compare per-words using a loop (comparing each word from one array with each word from another, and if they match, remove the whole array).
array_unique() example
<?php
$input = array("a" => "green", "red", "b" => "green", "blue", "red");
$result = array_unique($input);
print_r($result);
?>
output:
Array
(
[a] => green
[0] => red
[1] => blue
)
Source

Categories