Last name usort - php

I asked a similar question but still having issues when some aspects.
The way this php file is working is that a persons name is being stored in the database in the names cell, in the format John Doe(firstname lastname). So I've separated the name with this code, so surname, firstname:
foreach ($customer_names as $key => $value) {
$parts = explode(" ", $value->name);
$lastname = array_pop($parts);
$firstname = implode(" ", $parts);
$name = $lastname.", ".$firstname." ";
echo "<option value='$value->name'>$name </option>";
now that gives me a list of names like Doe, John.
However, I need to sort the names in order of the surname.
using usort. How would I do that? I've tried playing around with the code, but still is showing up in the order of the first name (set by the db query).
Still a bit new to usort functionality.

This should work:
usort($customer_names, function($customer1, $customer2) {
return strcmp(
substr($customer1->name, strrpos($customer1->name, " ")),
substr($customer2->name, strrpos($customer2->name, " "))
);
});
Your $customer_names array will then be sorted by the last name of the customer. Last name means the string after the last space, e.g. John Doe would be Doe. Mary Lou Foo would be Foo.
Please refer to http://php.net to learn more about the used functions.

//Program for sorting list of names according to last name
<?php
class array_sort
{
public $temp;
public function alhsort(array $sorted)
{
for($i=0; $i<count($sorted)-1; $i++){
for($j=$i+1; $j<count($sorted); $j++){
if(strcasecmp(end(explode(' ', $sorted[$i])), end(explode(' ', $sorted[$j])))>0){
$temp = $sorted[$i];
$sorted[$i] = $sorted[$j];
$sorted[$j] = $temp;
}
}
}
return $sorted;
}
}
$sortarray = new array_sort();
print_r($sortarray->alhsort(array('Ayush Jain', 'Abhishek Gupta', 'Rahul Rajput', 'Kapil Patel', 'Shobit Shrivastav', 'Hitesh Gupta')));
?>

Related

how can I compare that a string is a part of a large string , both strings are store in different array index

I've two arrays containing different strings in their index's and i want to compare these string to ensure that one string is either a sub string of other or not. for example
$final_array=array("BSSE (English) Mr. John","BSSE (Physics) Mr. jack","BSSE (Math) Mr. peter");
$teachers=array("Mr.John","Mr. peter","Mr. jack");
now I want to get all the classes that Mr. john teaches by comparing "teachers array" index with all the indexes of "final_array" to get the elements have a string part Mr. John..
I hope you people can understand my problem
As I said in my comment, this will only work if the teacher names are unique and if the teachers names are spelled the same in both arrays.
This loops through all the teachers and compares each teacher string with each class string. If the teacher name exists in one of the class names the code will run through the if statement.
foreach($teachers as $teacher) {
foreach($final_array as $class) {
if(strpos($class, $teacher) !== FALSE) {
//Do something
}
}
}
First of all, I recommend you to remove spaces from your strings
$string = str_replace(' ', '', $string);
Also make that string all lowercase
$string = strtolower($string);
That way, the comparison between the positions of the arrays will be easier:
$tcounter = 0;
$ccounter = 0;
foreach($teachers as $teacher) {
$tname = strtolower(str_replace(' ','', $teacher));
$tcounter ++;
foreach($final_array as $class) {
$cname = strtolower(str_replace(' ','', $class));
if(strpos($cname, $tname) !== FALSE) {
echo '$teachers["'.$tcounter.'"] found on $final_array["'.$ccounter.'"]';
}
$ccounter++;
}
$ccounter=0;
}

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

How to search for certain number of letter within a text file with PHP?

I have a large text file with names, location and date of birth of lots of people. I need to find names based on character size. How can I do this with PHP?
In the text file, data is organised like this:
Name-Location ID DOB
Bob-LA 110 12/01/1987
Lia-CA 111 11/09/1984
Neil-LA 112 17/10/1982
Emon-CA 113 07/12/1991
Elita-CA 113 13/06/1983
Ron-CA 114 16/02/1979
and so on
Now I wish to search for people with certain character name and with same location (say I wish to find all the people whose name has 4 letter and are from CA [Emon-CA]). How can I do that?
I can normally search through a file using PHP, where I know the string I am looking for. But here I actually don't know how to set the condition to show up my desired results. Can someone please help me?
Thanks in advance.
You can try
$filename = "log.txt";
foreach ( new TextFileFilterIterator($filename) as $line ) {
list($name, $location, $id, $dob) = $line;
if (strlen($name) == 4 && $location == "CA") {
echo implode(",", $line), PHP_EOL;
}
}
Output
Emon,CA,113,07/12/1991
Class Used
class TextFileFilterIterator extends ArrayIterator {
private $filter;
function __construct($filename) {
parent::__construct(array_filter(array_map("trim", file($filename))));
}
public function current() {
$c = array_filter(explode(" ", parent::current()));
list($n, $l) = explode("-", array_shift($c));
array_unshift($c, $n, $l);
return array_map("trim", $c);
}
}
I'd suggest using regular expressions, something like this:
// assume $text contains the contents of your text file
$namelength = 4; // change this as needed
$location = 'CA'; // again, change as needed
If you just want to count the results
$count = preg_match_all('|^\s*([\w]{'.$namelength.'})-'.$location.'\s*(\d+)\s*(\d{2}/\d{2}/\d{4})$|',$text,$matches);
Otherwise, If you want to do something with each match:
if(preg_match_all('|^\s*([\w]{'.$namelength.'})-'.$location.'\s*(\d+)\s*(\d{2}/\d{2}/\d{4})$|',$text,$matches)){
foreach($matches as $match){
$name = $match[1];
$id = $match[3];
$dob = $match[4];
// Do something with each name.
}
}

Array with empty values need to be discarded

Given, In a input form user can separate some specific names by new line and i am saving those names in an array. Then I print those names and at last say something like "thank you for the names".
$var = "name1
name2
";
$your_array = explode("\n", $var);
for($i=0; $i<(sizeof($your_array));$i++) {
echo ($your_array[$i]);
}
echo "Thank you for the names"
But the problem is if someone enter more than one newline before or after a name then the next name show after some distance like below
name1
name2
Thank you for the names
How can escape this and output as below
name1
name2
Thank you for the names
I tried to use array_filter() but it don't work here.
Update:
If someone input
$var = "name1\nname2\n\n\n
name3
name4";
output should be like
name1
name2
name3
name4
But all the answers show like
name1
name2
name3
name4
Let's use a foreach loop for the sake of simplicity...
1) We need to iterate through the new array and trim the names so we lose all whitespace.
2) We echo out the name, if and only if the length of the name is 1 or more.
3) We add on a <br> tag to make each name appear on a new line.
<?php
$var = "name1\nname2\n\n\n";
$your_array = explode("\n", $var);
foreach($your_array as $name)
{
if(preg_match("/[a-zA-Z0-9]{1,}/i", $name)) {
$name = trim($name);
echo (strlen($name) > 1) ? sprintf('%s<br>', $name) : '';
}
}
echo "Thank you for the names";
?>
$your_array = explode(PHP_EOL, $var);
$names = array();
for ($i = 0; $i < count($your_array); $i ++ )
{
// trim clean spaces and newlines surrounding each line
// resulting value is assigned to $test
// if this value is not empty the conditional is a true proposition
// so is assigned to $names
if ($test = trim($your_array[$i]))
$names[] = $test;
}
echo implode(PHP_EOL, $names) . PHP_EOL;
echo 'Thank you for the names.';
EDIT: using foreach
$your_array = explode(PHP_EOL, $var);
foreach ($your_array as $name)
{
if ($test = trim($name))
$names[] = $test;
}
if ($names)
{
// echo implode(PHP_EOL, $names) . PHP_EOL;
echo implode('<br />', $names) . '<br />';
echo 'Thank you for the names.';
}
else
echo 'Names missing.';
EDIT 2
trim accept a charlist to explicit removes, so if you want maintain spaces, make a list with newlines and carriage return only.
trim($name, "\r\n");
NOTE: PHP_EOL is the correct new line char depending of server (unix or windows).
Be a better PHP developer and use native PHP array functions:
$raw_arr = array(' trim ', 'fine', ' ');
array_walk($raw_arr, function(&$value) {
$value = trim($value);
});
$reduced_arr = array_filter($raw_arr);
print_r($reduced_arr);
Note: I have used a closure. If you are running PHP < 5.3, you'll need to move this to a UDF.
UPDATE
Seems like you don't wish to trim the user input. As such, you can drop array_walk and its closure.
$raw_arr = array('    trim  ', 'fine', '');
$reduced_arr = array_filter($raw_arr);
print_r($reduced_arr);
for($i=0; $i<(sizeof($your_array));$i++) {
if (empty($your_array[$i])) continue;
echo ($your_array[$i]);
}
echo "Thank you for the names"
You can use array_filter + array_map + trim to discard empty space
$var = "name1
name2
";
$array = array_filter(array_map("trim",explode("\n", $var)));
echo implode(PHP_EOL, $array) , PHP_EOL;
echo "Thank you for the names";
Or just use preg_match_all
preg_match_all("/\S?([a-z0-9]+)\S?/", $var,$array);
echo implode(PHP_EOL, $array[0]),PHP_EOL;
echo "Thank you for the names";
Both Would Output
name1
name2
Thank you for the names

PHP regex generator

I have now got a working regex string for the below needed criteria:
a one line php-ready regex that encompasses a number of keywords, and keyterms and will match at least one of them.
For example:
Keyterms:
apple
banana
strawberry
pear cake
Now if any of these key terms are found then it returns true. However, to add a little more difficulty here, the pear cake term should be split as two keywords which must both be in the string, but need not be together.
Example strings which should return true:
A great cake is made from pear
i like apples
i like apples and bananas
i like cakes made from pear and apples
I like cakes made from pears
The working regex is:
/\bapple|\bbanana|\bstrawberry|\bpear.*?\bcake|\bcake.*?\bpear/
Now I need a php function that will create this regex on the fly from an array of keyterms. The stickler is that a keyterm may have any number of keywords within that key. Only on of the keyterms need be found, but multiple can be present. As above all of the the words within a keyterm must appear in the string in any order.
I have written a function for you here:
<?php
function permutations($array)
{
$list = array();
for ($i=0; $i<=10000; $i++) {
shuffle($array);
$tmp = implode(',',$array);
if (isset($list[$tmp])) {
$list[$tmp]++;
} else {
$list[$tmp] = 1;
}
}
ksort($list);
$list = array_keys($list);
return $list;
}
function CreateRegex($array)
{
$toReturn = '/';
foreach($array AS $value)
{
//Contains spaces
if(strpos($value, " ") != false)
{
$pieces = explode(" ", $value);
$combos = permutations($pieces);
foreach($combos AS $currentCombo)
{
$currentPieces = explode(',', $currentCombo);
foreach($currentPieces AS $finallyGotIt)
{
$toReturn .= '\b' . $finallyGotIt . '.*?';
}
$toReturn = substr($toReturn, 0, -3) . '|';
}
}
else
{
$toReturn .= '\b' . $value . '|';
}
}
$toReturn = substr($toReturn, 0, -1) . '/';
return $toReturn;
}
var_dump(CreateRegex(array('apple', 'banana', 'strawberry', 'pear cake')));
?>
I got the permutations function from:
http://www.hashbangcode.com/blog/getting-all-permutations-array-php-74.html
But I would recommend to find a better function and use another one since just at first glance this one is pretty ugly since it increments $i to 10,000 no matter what.
Also, here is a codepad for the code:
http://codepad.org/nUhFwKz1
Let me know if there is something wrong with it!

Categories