A Harder Problem than You Might Think

February 3, 2014 at 10:30 pm

I recently had the problem of breaking an address into a specific sized array. For example:

$s = "203 Wembley Square, Wembley Square Road, Cape Town, South Africa, 8001";

The result must be evenly spread strings across a new array, of which only the maximum size is known. So, for example, if I specify that the maximum length must be 3, the result should be:

Array
(
    [0] => 203 Wembley Square, Wembley Square Road
    [1] => Cape Town, South Africa
    [2] => 8001
)

It might not be completely apparent why this is useful, but let me explain what I used it for. One of the tables in my database had three fields, namely:

  • address_line_1
  • address_line_2
  • address_line_3

For the scenario, there was no way that I could alter the database to cater for more or less fields. However, due to improvements on the system, there was a form that allowed users to enter the following “address” details:

  • Street Name
  • Building Name
  • City
  • Area Code
  • Country

So effectively, I had to map 5 lines onto 3 fields. The result I desired was:

  • address_line_1 = Street Name, Building Name
  • address_line_2 = City, Area Code
  • address_line_3 = Country

After exploring a host of options, I finally came to the following function that did what I want:

function splitArray($array, $maxSize = 3, $splitOn = array("\r\n", ",", "\r", "\n"))    
{
	# Split the array on multiple specified characters
	$arrayParts = explode(chr(1),str_replace($splitOn,chr(1),$array));

	# Format parts, remove invalid sections
	$finalAddressParts = array();
	foreach ($arrayParts as $a) {
	    $formatted = trim($a);
	    if (empty($formatted)) continue;
	    $finalAddressParts[] = $formatted;
	}
	$arrayParts = $finalAddressParts;

	# Create the chunks
	$maxPerLine = max(round(sizeof($arrayParts) / $maxSize), 1);
	$chunks = array_chunk($arrayParts, $maxPerLine);

	for ($i=0; $i < $maxSize; $i++)  {
	    $arrayLines[$i] = '';
	}

	$count = 0;
	foreach ($chunks as $chunk) {
	    $arrayLines[$count] = implode(", ", $chunk);
	    $count++;
	}

	return $arrayLines;
}

I'm sure there must be a shorter way to write this, and would love for anyone who knows of a way, to post it below. This is the best I could come up with that was both short and easy to read.