Generating a PHP list with "and" - php

What's an efficient way to format an array in PHP as a list with commas and the word "and" before the last element?
$array = Array('a','b','c','d');
I want to produce the string "a, b, c, and d"

I would modify the $array in place to add the "and", and then join the parts with commas for output:
array_push($array, " and " . array_pop($array));
print join(", ", $array);
But you might as well just use array_pop to separate the last entry, join the rest, and then append the "and" and last entry.

I suppose that should do it:
$array[ sizeof($array) - 1 ] = 'and ' . $array[ sizeof($array) - 1 ];
$list = implode(', ', $array);

There are a number of ways you could do it, here is one:
<?
$array = Array('a','b','c','d');
$string=implode(',',$array);
$nstring=substr_replace($string,' and ', -1, 0);
echo $nstring;

<?php
$array = Array('a','b','c','d');
$array[count($array)-1] = 'and '.$array[count($array)-1];
echo implode($array, ', ');
?>
http://codepad.org/7oeni6xv

Try:
function arrayEnum($array)
{
$string = '';
for (i = 0, $l = count($array); i < $l; ++i)
{
$string .= $array[$i];
if (i != ($l -1)) $string .= ', ';
if (i == ($l -2)) $string .= 'and '
}
}
$array = Array('a','b','c','d');
echo $array; // a, b, c, and d
$array = Array('one','two','three','four');
echo $array; // one, two, three and four
That function will work with any length of data.

Related

Want to iterate a string that after each charater there will be a space in PHP

I want to iterate a string in the manner that after each character there should be a space and there will be new string(word) as per the main string character count.
For example
If I put the string "v40eb" as an input. Then Output be something like below.
v 40eb
v4 0eb
v40 eb
v40e b
OR
In Array form like below.
[0]=>v 40eb[1]=>v4 0eb[2]=>v40 eb[3]=>v40e b
I am using PHP.
Thanks
Well, you can divide the process of putting a space into 2 parts.
Get first part of the substring, append a space.
Get second part of the substring and join them together.
Use substr() to get a substring of a string.
Snippet:
<?php
$str = "v40eb";
$result = [];
$len = strlen($str);
for($i=0;$i<$len;++$i){
$part1 = substr($str,0,$i+1);
if($i < $len-1) $part1 .= " ";
$part2 = substr($str,$i+1);
$result[] = $part1 . $part2;
}
print_r($result);
Demo: https://3v4l.org/XGN0a
You could simply loop over the char positions and use substr to get the two parts for each:
$input = 'v40eb';
$combinations = [];
for ($charPos = 1, $charPosMax = strlen($input); $charPos < $charPosMax; $charPos++) {
$combinations[] = substr($input, 0, $charPos) . ' ' . substr($input, $charPos);
}
print_r($combinations);
Demo: https://3v4l.org/EeT1V
$input = 'v40eb';
for($i = 1; $i< strlen($input); $i++) {
$array = str_split($input);
array_splice($array, $i, 0, ' ');
$output[] = implode($array);
}
print_r($output);
Dont forget to check the codec. You might use mb_-prefix to use the multibyte-functions.

Merging two words together letter by letter in php. How to make it work?

How to merge two words together letter by letter in php on the following way:
Input #1: Apricot
Input #2: Kiwi
Expected output: AKpirwiicot.
So that if one word's characters are more than the other, it simply writes it down until the end.
I tried it by this logic:
Input smthing
str_split()
array_merge()
But I failed. Any solutions appreciated.
$string1 and $string2 can be in any order.
$string1=str_split("Apricot");
$string2=str_split("Kiwi");
if(count($string2)>count($string1)){
$templ = $string1;
$string1 = $string2;
$string2 = $temp;
}
$result = "";
foreach($string1 as $key => $var){
{
$result.=$var;
if(isset($string2[$key])){
$result.$string2[$key];
}
}
echo $result;
Array_merge() also sticks one array on the end of the other so it wouldn't do what you are looking for I believe.
edit : ive adjusted to take into account no order, like #nikkis answer.
How about this:
def str_merge(a, b):
s = ''
k = min(len(a), len(b))
for i in range(k):
s += a[i] + b[i]
s += a[k:] + b[k:]
return s
In PHP:
function merge($a, $b)
{
$s = '';
$k = min(strlen($a), strlen($b));
for($i=0; $i<$k; $i++)
{
$s = $s . $a[$i] . $b[$i];
}
$s = $s . substr($a, $k) . substr($b, $k);
}
Please forgive my PHP, not my strongest language...

How to truncate a delimited string in PHP?

I have a string of delimited numerical values just like this:
5|2288|502|4208|55|23217|235|10|3845|19053|1885|61|324|9004| ...etc.
Depending on the circumstance, the string may have only 1 value, 15 values, all the way up to 100s of values, all pipe delimited.
I need to count off (and keep/echo) the first 10 values and truncate everything else after that.
I've been looking at all the PHP string functions, but have been unsuccessful in finding a method to handle this directly.
Use explode() to separate the elements into an array, then you can slice off the first 10, and implode() them to create the new string.
$arr = "5|2288|502|4208|55|23217|235|10|3845|19053|1885|61|324|9004";
$a = explode ('|',$arr);
$b = array_slice($a,0,10);
$c = implode('|', $b);
Use PHP Explode function
$arr = explode("|",$str);
It will break complete string into an array.
EG: arr[0] = 5, arr[1] = 2288 .....
I would use explode to separate the string into an array then echo the first ten results like this
$string = "5|2288|502|4208|55|23217|235|10|3845|19053|1885|61|324|9004";
$arr = explode("|", $string);
for($i = 0; $i < 10; $i++){
echo $arr[$i];
}
Please try below code
$str = '5|2288|502|4208|55|23217|235|10|3845|19053|1885|61|324';
$arrayString = explode('|', $str);
$cnt = 0;
$finalVar = '';
foreach ($arrayString as $data) {
if ($cnt > 10) {
break;
}
$finalVar .= $data . '|';
$cnt++;
}
$finalVar = rtrim($finalVar, '|');
echo $finalVar;

Efficient check for array items in a string

I have an array like:
arr = array("*" , "$" , "and" , "or" , "!" ,"/");
and another string like :
string = "this * is very beautiful but $ is more important in life.";
I'm looking the most efficient way with the lowest cost to find the member of the array in this string. Also I need to have an array in result that can show which members exist in the string.
The easiest way is using a for loop but I believe there should be more efficient ways to do this in PHP.
$arr=array("*" , "$" , "#" , "!");
$r = '~[' . preg_quote(implode('', $arr)) . ']~';
$str = "this * is very beautiful but $ is more important in life.";
preg_match_all($r, $str, $matches);
echo 'The following chars were found: ' . implode(', ', $matches[0]);
If you are looking for the most efficient way, the result of the following code is:
preg:1.03257489204
array_intersect:2.62625193596
strpos:0.814728021622
It looks like looping the array and matching using strpos is the most efficient way.
$arr=array("*" , "$" , "#" , "!");
$string="this * is very beautiful but $ is more important in life.";
$time = microtime(true);
for ($i=0; $i<100000; $i++){
$r = '~[' . preg_quote(implode('', $arr)) . ']~';
$str = "this * is very beautiful but $ is more important in life.";
preg_match_all($r, $str, $matches);
}
echo "preg:". (microtime(true)-$time)."\n";
$time = microtime(true);
for ($i=0; $i<100000; $i++){
$str = str_split($string);
$out = array_intersect($arr, $str);
}
echo "array_intersect:". (microtime(true)-$time)."\n";
$time = microtime(true);
for ($i=0; $i<100000; $i++){
$res = array();
foreach($arr as $a){
if(strpos($string, $a) !== false){
$res[] = $a;
}
}
}
echo "strpos:". (microtime(true)-$time)."\n";
You can use array_insersect
$string = "this * is very beautiful but $ is more important in life.";
$arr=array("*" , "$" , "#" , "!");
$str = str_split($string);
$out = array_intersect($arr, $str);
print_r($out);
This code will produce the following output
Array ( [0] => * [1] => $ )

Implode an array with ", " and add "and " before the last item

This array holds a list of items, and I want to turn it into a string, but I don't know how to make the last item have a &/and before it instead of a comma.
1 => coke 2=> sprite 3=> fanta
should become
coke, sprite and fanta
This is the regular implode function:
$listString = implode(', ', $listArrau);
What's an easy way to do it?
A long-liner that works with any number of items:
echo join(' and ', array_filter(array_merge(array(join(', ', array_slice($array, 0, -1))), array_slice($array, -1)), 'strlen'));
Or, if you really prefer the verboseness:
$last = array_slice($array, -1);
$first = join(', ', array_slice($array, 0, -1));
$both = array_filter(array_merge(array($first), $last), 'strlen');
echo join(' and ', $both);
The point is that this slicing, merging, filtering and joining handles all cases, including 0, 1 and 2 items, correctly without extra if..else statements. And it happens to be collapsible into a one-liner.
I'm not sure that a one liner is the most elegant solution to this problem.
I wrote this a while ago and drop it in as required:
/**
* Join a string with a natural language conjunction at the end.
* https://gist.github.com/angry-dan/e01b8712d6538510dd9c
*/
function natural_language_join(array $list, $conjunction = 'and') {
$last = array_pop($list);
if ($list) {
return implode(', ', $list) . ' ' . $conjunction . ' ' . $last;
}
return $last;
}
You don't have to use "and" as your join string, it's efficient and works with anything from 0 to an unlimited number of items:
// null
var_dump(natural_language_join(array()));
// string 'one'
var_dump(natural_language_join(array('one')));
// string 'one and two'
var_dump(natural_language_join(array('one', 'two')));
// string 'one, two and three'
var_dump(natural_language_join(array('one', 'two', 'three')));
// string 'one, two, three or four'
var_dump(natural_language_join(array('one', 'two', 'three', 'four'), 'or'));
It's easy to modify to include an Oxford comma if you want:
function natural_language_join( array $list, $conjunction = 'and' ) : string {
$oxford_separator = count( $list ) == 2 ? ' ' : ', ';
$last = array_pop( $list );
if ( $list ) {
return implode( ', ', $list ) . $oxford_separator . $conjunction . ' ' . $last;
}
return $last;
}
You can pop last item and then join it with the text:
$yourArray = ('a', 'b', 'c');
$lastItem = array_pop($yourArray); // c
$text = implode(', ', $yourArray); // a, b
$text .= ' and '.$lastItem; // a, b and c
Try this:
$str = array_pop($array);
if ($array)
$str = implode(', ', $array)." and ".$str;
Another possible short solution:
$values = array('coke', 'sprite', 'fanta');
$values[] = implode(' and ', array_splice($values, -2));
print implode(', ', $values); // "coke, sprite and fanta"
It works fine with any number of values.
My go-to, similar to Enrique's answer, but optionally handles the oxford comma.
public static function listifyArray($array,$conjunction='and',$oxford=true) {
$last = array_pop($array);
$remaining = count($array);
return ($remaining ?
implode(', ',$array) . (($oxford && $remaining > 1) ? ',' : '') . " $conjunction "
: '') . $last;
}
I know im way to late for the answer, but surely this is a better way of doing it?
$list = array('breakfast', 'lunch', 'dinner');
$list[count($list)-1] = "and " . $list[count($list)-1];
echo implode(', ', $list);
This can be done with array_fill and array_map. It is also a one-liner (seems that many enjoy them)), but formated for readability:
$string = implode(array_map(
function ($item, $glue) { return $item . $glue; },
$array,
array_slice(array_fill(0, count($array), ', ') + ['last' => ' and '], 2)
));
Not the most optimal solution, but nevertheless.
Here is the demo.
try this
$arr = Array("coke","sprite","fanta");
$str = "";
$lenArr = sizeof($arr);
for($i=0; $i<$lenArr; $i++)
{
if($i==0)
$str .= $arr[$i];
else if($i==($lenArr-1))
$str .= " and ".$arr[$i];
else
$str .= " , ".$arr[$i];
}
print_r($str);
Try this,
<?php
$listArray = array("coke","sprite","fanta");
foreach($listArray as $key => $value)
{
if(count($listArray)-1 == $key)
echo "and " . $value;
else if(count($listArray)-2 == $key)
echo $value . " ";
else
echo $value . ", ";
}
?>
I just coded this based on the suggestions on this page. I left in my pseudo-code in the comments in case anyone needed it. My code differs from others here as it handles different-sized arrays differently and uses the Oxford comma notation for lists of three or more.
/**
* Create a comma separated list of items using the Oxford comma notation. A
* single item returns just that item. 2 array elements returns the items
* separated by "and". 3 or more items return the comma separated list.
*
* #param array $items Array of strings to list
* #return string List of items joined by comma using Oxford comma notation
*/
function _createOxfordCommaList($items) {
if (count($items) == 1) {
// return the single name
return array_pop($items);
}
elseif (count($items) == 2) {
// return array joined with "and"
return implode(" and ", $items);
}
else {
// pull of the last item
$last = array_pop($items);
// join remaining list with commas
$list = implode(", ", $items);
// add the last item back using ", and"
$list .= ", and " . $last;
return $list;
}
}
This is quite old at this point, but I figured it can't hurt to add my solution to the pile. It's a bit more code than other solutions, but I'm okay with that.
I wanted something with a bit of flexibility, so I created a utility method that allows for setting what the final separator should be (so you could use an ampersand, for instance) and whether or not to use an Oxford comma. It also properly handles lists with 0, 1, and 2 items (something quite a few of the answers here do not do)
$androidVersions = ['Donut', 'Eclair', 'Froyo', 'Gingerbread', 'Honeycomb', 'Ice Cream Sandwich', 'Jellybean', 'Kit Kat', 'Lollipop', 'Marshmallow'];
echo joinListWithFinalSeparator(array_slice($androidVersions, 0, 1)); // Donut
echo joinListWithFinalSeparator(array_slice($androidVersions, 0, 2)); // Donut and Eclair
echo joinListWithFinalSeparator($androidVersions); // Donut, Eclair, Froyo, Gingerbread, Honeycomb, Ice Cream Sandwich, Jellybean, Kit Kat, Lollipop, and Marshmallow
echo joinListWithFinalSeparator($androidVersions, '&', false); // Donut, Eclair, Froyo, Gingerbread, Honeycomb, Ice Cream Sandwich, Jellybean, Kit Kat, Lollipop & Marshmallow
function joinListWithFinalSeparator(array $arr, $lastSeparator = 'and', $oxfordComma = true) {
if (count($arr) > 1) {
return sprintf(
'%s%s %s %s',
implode(', ', array_slice($arr, 0, -1)),
$oxfordComma && count($arr) > 2 ? ',':'',
$lastSeparator ?: '',
array_pop($arr)
);
}
// not a fan of this, but it's the simplest way to return a string from an array of 0-1 items without warnings
return implode('', $arr);
}
OK, so this is getting pretty old, but I have to say I reckon most of the answers are very inefficient with multiple implodes or array merges and stuff like that, all far more complex than necessary IMO.
Why not just:
implode(',', array_slice($array, 0, -1)) . ' and ' . array_slice($array, -1)[0]
Simple human_implode using regex.
function human_implode($glue = ",", $last = "y", $elements = array(), $filter = null){
if ($filter) {
$elements = array_map($filter, $elements);
}
$str = implode("{$glue} ", $elements);
if (count($elements) == 2) {
return str_replace("{$glue} ", " {$last} ", $str);
}
return preg_replace("/[{$glue}](?!.*[{$glue}])/", " {$last}", $str);
}
print_r(human_implode(",", "and", ["Joe","Hugh", "Jack"])); // => Joe, Hugh and Jack
Another, although slightly more verbose, solution I came up with. In my situation, I wanted to make the words in the array plural, so this will add an "s" to the end of each item (unless the word already ends in 's':
$models = array("F150","Express","CR-V","Rav4","Silverado");
foreach($models as $k=>$model){
echo $model;
if(!preg_match("/s|S$/",$model))
echo 's'; // add S to end (if it doesn't already end in S)
if(isset($models[$k+1])) { // if there is another after this one.
echo ", ";
if(!isset($models[$k+2]))
echo "and "; // If this is next-to-last, add ", and"
}
}
}
outputs:
F150s, Express, CR-Vs, Rav4s, and Silverados
It's faster then deceze's solution and works with huge arrays (1M+ elements). The only flaw of both solutions is a poor interaction with a number 0 in a less then three elements arrays becouse of array_filter use.
echo implode(' and ', array_filter(array_reverse(array_merge(array(array_pop($array)), array(implode(', ',$array))))));

Categories