Skip to content

Instantly share code, notes, and snippets.

@vrakita
Last active July 18, 2019 08:28
Show Gist options
  • Save vrakita/4a52787cad4d1f48f1e58683390da33c to your computer and use it in GitHub Desktop.
Save vrakita/4a52787cad4d1f48f1e58683390da33c to your computer and use it in GitHub Desktop.
Order parser
<?php
class Parser {
CONST break = '^';
protected function sorter($a, $b): int
{
return strlen($b) - strlen($a);
}
public function sortItems($items): array
{
usort($items, [$this, 'sorter']);
return $items;
}
protected function getPositions(string $item, string $order): array
{
$positions = [];
$start = 0;
while(($pos = strpos(strtolower($order), strtolower($item), $start)) !== false) {
$positions[] = $pos;
$start = $pos + 1;
}
return $positions;
}
/**
* Finds quantity for specific item
*
* @param $item
* @param $order
* @return int
*/
public function findQuantity($item, $order): int
{
$result = 0;
if(($position = strpos(strtolower($order), strtolower($item))) === false) {
return $result;
}
foreach($this->getPositions($item, $order) as $pos) {
$innerValue = '';
$numberSeek = false;
$position = $pos + strlen($item);
if( ! isset($order[$position])) {
$result++;
continue;
}
while(isset($order[$position])) {
if($numberSeek && ! is_numeric($order[$position])) {
break;
}
if($order[$position] === ' ') {
$position++;
continue;
}
if ( ! is_numeric($order[$position]) || ctype_alpha($order[$position])) {
$result++;
break;
}
if( is_numeric($order[$position])) {
$numberSeek = true;
$innerValue .= $order[$position];
}
$position++;
}
$result += (int) $innerValue;
}
return (int) $result;
}
/**
* Parse, group and calculate given order based on available
* items and give order
*
* @param array $items i.e. ['yes a', 'yes b']
* @param string $order i.e. 'yes a 15, yes b 3'
* @return array ['yes a' => 15, 'yes b' => 3]
*/
public function parseOrder(array $items, string $order): array
{
$out = [];
$items = $this->sortItems($items);
$order = strtolower($order);
foreach($items as $item) {
if(($pos = strpos(strtolower($order), strtolower($item))) !== false) {
if( ! $quantity = $this->findQuantity($item, $order)) {
$quantity = 1;
}
$out[$item] = (isset($out[$item])) ? ($out[$item] += $quantity) : $quantity;
$partial = substr($order, $pos, strlen($item));
$order = str_replace($partial, self::break, $order);
}
}
return $out;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment