HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMinor

Efficiently displaying elements in an array

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
arrayefficientlyelementsdisplaying

Problem

I wrote the below method to list out the elements of an array, as well as adding the Oxford comma to the list if desired. However, my for-loop looks, perhaps, a little convoluted. Is there a better way to handle clearly both the Oxford comma and the ability to add a conjunction?

function listOut($array = array(), $oxford = false, $conjunction = 'and') {
    $count = is_array($array) ? count($array) : 0;

    switch($count) {
        case 0: // Either not an array or an empty array
            return '';

        case 1: // Only one element in the array, return it
            return $array[0];

        case 2: // Two elements; join them together with the conjunction
            return "{$array[0]} {$conjunction} {$array[1]}";

        default: // At least two elements, join with commas and conjunction
            $s = ", ";
            $t = "";
            for($i = 0; $i  0) { 
                    $t .= $s;
                }

                // Add the element to the return string
                $t .= $array[$i];
            }
            return $t;
    }
}

$array1 = array('orange');
$array2 = array('white', 'gold');
$array3 = array('black', 'white', 'purple');

echo listOut($array1); // orange
echo listOut($array2); // white and gold
echo listOut($array3); // black, white and purple

echo listOut($array1, true); // orange
echo listOut($array2, true); // white and gold
echo listOut($array3, true); // black, white, and purple

Solution

You can effectively get rid of the switch statement as well as the is_array check in the count ternary if you do the check in the beginning (and exit early at that - so not wasting any cycles).

You can also get rid of

# Only prepend comma if not the first element
if($i > 0) { 
    $output .= $separator;
}


If you add a ternary concat to $output (at the expense of gaining 2 opcode calls over the if/else). This would be the function after cleaning it:

function listOut($array = array(), $oxford = false, $conjunction = 'and', $separator = ", ") {
    if(!is_array($array)){ # We're expecting an array 
        return false;
    }

    $count = count($array) ?: 0;
    $output = "";

    if($count == 2){ return implode(" $conjunction ", $array); }

    for($i = 0; $i  0 ? $separator : "") . $array[$i];
    }

    return $output;
}


and the test outputs:

$array = 'blue';
$array1 = array('orange');
$array2 = array('white', 'gold');
$array3 = array('black', 'white', 'purple');
$array4 = array('black', 'white', 'purple', 'gold');

echo listOut($array) . "";
echo listOut($array1) . ""; // orange
echo listOut($array2) . ""; // white and gold
echo listOut($array3, true) . ""; // black, white and purple
echo listOut($array4) . ""; // black, white and purple


Results:

false
orange
white and gold
black, white, and purple
black, white, purple and gold

Code Snippets

# Only prepend comma if not the first element
if($i > 0) { 
    $output .= $separator;
}
function listOut($array = array(), $oxford = false, $conjunction = 'and', $separator = ", ") {
    if(!is_array($array)){ # We're expecting an array 
        return false;
    }

    $count = count($array) ?: 0;
    $output = "";

    if($count == 2){ return implode(" $conjunction ", $array); }

    for($i = 0; $i < $count; $i++) {
        # Add a conjunction if it's the last element in the array
        if($i + 1 === $count) {
            $separator = $oxford ? $separator . "$conjunction " : " $conjunction ";
        }

        # Add the element to the return string
        $output .= ($i > 0 ? $separator : "") . $array[$i];
    }

    return $output;
}
$array = 'blue';
$array1 = array('orange');
$array2 = array('white', 'gold');
$array3 = array('black', 'white', 'purple');
$array4 = array('black', 'white', 'purple', 'gold');

echo listOut($array) . "<br>";
echo listOut($array1) . "<br>"; // orange
echo listOut($array2) . "<br>"; // white and gold
echo listOut($array3, true) . "<br>"; // black, white and purple
echo listOut($array4) . "<br>"; // black, white and purple
false
orange
white and gold
black, white, and purple
black, white, purple and gold

Context

StackExchange Code Review Q#64294, answer score: 2

Revisions (0)

No revisions yet.