public function find(callable $predicate, bool $findKeys = null, int $limit = 0): array
	{
		$data = [];
		$found = 0;
		
		if ($limit >= 0)
		{
			foreach ($this->data as $key => $value)
			{
				if ($predicate($value, $key) === true)
				{
					$found++;
					
					if ($findKeys === null)
					{
						$data[$key] = $value;
					}
					else
					{
						$data[] = $findKeys ? $key : $value;
					}
					
					if ($found === $limit)
					{
						break;
					}
				}
			}
		}
		else
		{
			// iterate in reverse rather than reversing the whole array or trimming all matches to the limit
			end($this->data);
			
			for ($i = 0; $i < count($this->data); $i++)
			{
				$key = $this->key();
				$value = $this->current();
				
				if ($predicate($value, $key) === true)
				{
					$found++;
					
					if ($findKeys === null)
					{
						$data[$key] = $value;
					}
					else
					{
						$data[] = $findKeys ? $key : $value;
					}
					
					if ($found === -$limit)
					{
						break;
					}
				}
				
				$this->prev();
			}
			
			$this->rewind();
			
			// entries need to be reversed otherwise they'll be in the wrong order
			$data = array_reverse($data, ($findKeys === null));
		}
		
		return $data;
	}