1 && !in_array($w, $filler, true)) { $kept[$w] = true; } } $kept = array_keys($kept); sort($kept, SORT_STRING); return $kept ? 'plain:' . implode(' ', $kept) : ''; } function usedkit_median($values) { $values = array_values($values); $n = count($values); if (!$n) { return null; } sort($values); return $n % 2 ? $values[intdiv($n, 2)] : ($values[$n / 2 - 1] + $values[$n / 2]) / 2; } /** * What the shop's sales of one model say. `$sales` is a list of * ['price' => float, 'days' => int|null, 'at' => unix time, 'grade' => string]. * Items sold for parts are left out: their price says what the fault cost, not what the * model is worth. */ function usedkit_reference_stats($sales) { $sales = array_values(array_filter($sales, function ($s) { return ($s['grade'] ?? '') !== 'parts' && $s['price'] > 0; })); if (!$sales) { return null; } $prices = array_column($sales, 'price'); $days = array_filter(array_column($sales, 'days'), function ($d) { return $d !== null; }); usort($sales, function ($a, $b) { return $b['at'] <=> $a['at']; }); return array( 'count' => count($sales), 'median' => usedkit_median($prices), 'low' => min($prices), 'high' => max($prices), 'days' => $days ? (int) round(usedkit_median($days)) : null, 'last' => $sales[0]['at'], 'sales' => array_slice($sales, 0, 5), ); }