Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI Workflow

on:
push:
branches: [ master, '2.0' ]
branches: [ master ]
pull_request:
branches: [ master ]

Expand All @@ -17,6 +17,8 @@ jobs:
- '7.3'
- '7.4'
- '8.0'
- '8.1'
- '8.2'

steps:
- name: Checkout code
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
vendor
.idea
composer.lock
.phpunit.result.cache
32 changes: 0 additions & 32 deletions .scrutinizer.yml

This file was deleted.

14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
[![License](https://poser.pugx.org/bentools/picker/license)](https://packagist.org/packages/bentools/picker)
[![Build Status](https://img.shields.io/travis/bpolaszek/picker/master.svg?style=flat-square)](https://travis-ci.org/bpolaszek/picker)
[![Coverage Status](https://coveralls.io/repos/github/bpolaszek/picker/badge.svg?branch=master)](https://coveralls.io/github/bpolaszek/picker?branch=master)
[![Quality Score](https://img.shields.io/scrutinizer/g/bpolaszek/picker.svg?style=flat-square)](https://scrutinizer-ci.com/g/bpolaszek/picker)
[![Total Downloads](https://poser.pugx.org/bentools/picker/downloads)](https://packagist.org/packages/bentools/picker)

# Picker

This simple library will help you pick a random item through a collection of items (string, objects, ints, whatever),
This simple library will help you pick a random item through a collection of items (string, objects, ints, whatever),
by optionally giving them a weight.

Usage
Expand Down Expand Up @@ -47,6 +46,17 @@ $picker = Picker::create()->withItems(['foo', 'bar', 'baz']);
echo $picker->pick(); // Will be a truly random value between foo, bar and baz
```

### Shift

The picker can optionally shift items once they're picked:

```php
$picker = Picker::create(shift: true)->withItems(['foo', 'bar']);
$picker->pick(); // let's assume `foo` is picked
$picker->pick(); // only `bar` remains
$picker->pick(); // RuntimeException
```

Installation
------------

Expand Down
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,10 @@
"squizlabs/php_codesniffer": "@stable",
"symfony/var-dumper": "^5.0",
"pestphp/pest": "^1.0"
},
"config": {
"allow-plugins": {
"pestphp/pest-plugin": true
}
}
}
17 changes: 14 additions & 3 deletions src/Picker.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,23 @@ final class Picker
*/
private $items = [];

public function __construct(int $defaultWeight = 1)
/**
* @var bool
*/
private $shift;

public function __construct(int $defaultWeight = 1, bool $shift = false)
{
if ($defaultWeight < 0) {
throw new \InvalidArgumentException('`defaultWeight` must be a positive integer.');
}
$this->defaultWeight = $defaultWeight;
$this->shift = $shift;
}

public static function create(int $defaultWeight = 1): self
public static function create(int $defaultWeight = 1, bool $shift = false): self
{
return new self($defaultWeight);
return new self($defaultWeight, $shift);
}

public function withItem($item, ?int $weight = null): self
Expand Down Expand Up @@ -72,6 +78,11 @@ public function pick()

[$item] = $this->items[$index];

if ($this->shift) {
unset($this->items[$index]);
$this->items = \array_values($this->items);
}

return $item;
}
}
16 changes: 16 additions & 0 deletions tests/PickerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,19 @@
expect(\count($foos))->toEqualWithDelta(800, 50);
expect(\count($bars))->toEqualWithDelta(200, 50);
});

it('can shift items once they\'re picked', function () {
$picker = Picker::create(1, true);
$picker = $picker->withItem('foo', 1000000);
$picker = $picker->withItem('bar', 1);

expect($picker->pick())->toBe('foo'); // 1 chance out of 1 million it's `bar`!
expect($picker->pick())->toBe('bar');
try {
$picker->pick(); // Should throw an exception
expect(true)->toBeFalse();
} catch (\Exception $e) {
expect($e)->toBeInstanceOf(\RuntimeException::class);
expect($e->getMessage())->toBe('Nothing to pick.');
}
});