Skip to content

Instantly share code, notes, and snippets.

@oliviagardiner
Last active January 31, 2022 21:14
Show Gist options
  • Save oliviagardiner/15258196b4aff74a121d14503b7856e5 to your computer and use it in GitHub Desktop.
Save oliviagardiner/15258196b4aff74a121d14503b7856e5 to your computer and use it in GitHub Desktop.
Correcting my own mistakes on a practice task
<?php
/**
Write a wrapper class that should encapsulate an array. Validate that the array only has integer elements. If not, raise an exception.
Implement a method that returns with numbers from the array that OCCURS odd number of times.
*/
// original
/*
class ArrayWrapper
{
public $arr;
function __construct(array $arr) {
try {
$this->validateOnlyInteger($arr);
$this->arr = $arr;
} catch (\Exception $e) {
throw new InvalidArgumentException($e->getMessage());
}
}
// NOTE1: missing "function"
// NOTE2: doesn't make sense for this to be private if the propery is public, and we may need to re-validate if the property gets reassigned
// NOTE3: i mentioned that i validated the array being an array because i didn't use type hinting
private validateOnlyInteger($arr) {
if (!is_array($arr)) {
throw new InvalidArgumentException("The argument is not an array!");
} else {
$integers = array_filter($arr, 'is_int');
if ($integers != $arr) {
throw new InvalidArgumentException("The array must contain only integers!");
}
}
}
// NOTE1: missing "function"
// NOTE2: the interviewer hinted that there was a different single loop solution
public getOddOccurence(): array {
$output = [];
// NOTE4: sort returns a boolean, this won't work
$sortedarr = sort($this->arr);
foreach ($sortedarr as $key => $value) {
// NOTE3: missing "isset"
if (!$output[$value]) {
$output[$value] = 1;
} else {
$output[$value] += 1;
}
if ($key !== 0 && $sortedarr[$key - 1] !== $value) {
// NOTE5: i explained how i would handle the last element of the array but i had no time left to code it
// NOTE6: undefined offset problem
if (!($output[$key - 1] & 1)) {
unset($output[$key - 1]);
}
}
}
return $output;
}
}
*/
// fixed/updated
class UpdatedArrayWrapper
{
public $arr;
function __construct(array $arr)
{
try {
$this->validateOnlyInteger($arr);
$this->arr = $arr;
} catch (\Exception $e) {
throw new InvalidArgumentException($e->getMessage());
}
}
public function validateOnlyInteger(array $arr)
{
$integers = array_filter($arr, 'is_int');
if ($integers != $arr) {
throw new InvalidArgumentException("The array must contain only integers!");
}
}
public function getOddOccurences(): array
{
$output = [];
$sortedarr = $this->arr;
sort($sortedarr);
foreach ($sortedarr as $key => $value) {
$output[$value] = isset($output[$value]) ? $output[$value] + 1 : 1;
if (($key !== 0 && end($output) !== $value) || $key === count($sortedarr) - 1) {
if (!(end($output) & 1)) {
array_pop($output);
}
}
}
return array_keys($output);
}
}
$arr = [1, 1, 1, 5, 6, 2, 2, 5, 6, 9, 2];
$wrapper = new UpdatedArrayWrapper($arr);
print_r($wrapper->getOddOccurences());
/**
* Test cases:
* - if a non-array is passed as a dependency, a TypeError is thrown
* - if an array is passed that has non-integers in it, an InvalidArgumentException is thrown
* - if an array of integer is passed, the instantiation can be completed with no errors
* - the method returns the correct output for odd occurences
* - the method returns an empty array if every element occurs even times
*/
/**
* Questions:
* - what happens when an empty array is passed (should we throw an exception or add a shortcut to the method if the array is empty)?
* - does the order of the elements in the return array matter (is it wrong to sort the array for processing)?
*/
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment