mirror of
https://github.com/robonen/tools.git
synced 2026-03-20 10:54:44 +00:00
refactor(repo): cleanup
This commit is contained in:
@@ -1,4 +0,0 @@
|
|||||||
# toolkit
|
|
||||||
My most frequently used tools in programming
|
|
||||||
|
|
||||||
- [Plural](/plural) (TS, PHP)
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
# Функция изменения формы слов в зависимости от числительного
|
|
||||||
|
|
||||||
Часто встречается задача вывода правильного окончания слова с предшествующим ему числом.
|
|
||||||
|
|
||||||
Например:
|
|
||||||
|
|
||||||
- 1 депутат
|
|
||||||
- 2–4 депутат**а**
|
|
||||||
- 0, 5-9 или 10 депутат**ов**
|
|
||||||
|
|
||||||
## Примеры исользования
|
|
||||||
|
|
||||||
### Typescript
|
|
||||||
```typescript
|
|
||||||
import { plural } from 'plural';
|
|
||||||
|
|
||||||
const totalOrders = 2;
|
|
||||||
|
|
||||||
const words = ['заказ', 'заказа', 'заказов'];
|
|
||||||
|
|
||||||
const result = `${totalOrders} ${plural(totalOrders, words)}`;
|
|
||||||
|
|
||||||
console.log(result); // 2 заказа
|
|
||||||
```
|
|
||||||
|
|
||||||
### PHP
|
|
||||||
```php
|
|
||||||
include 'plural.php';
|
|
||||||
|
|
||||||
$totalOrders = 2;
|
|
||||||
|
|
||||||
$words = ['заказ', 'заказа', 'заказов'];
|
|
||||||
|
|
||||||
$result = "{$totalOrders} {plural($totalOrders, $words)}";
|
|
||||||
|
|
||||||
echo result; // 2 заказа
|
|
||||||
```
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
function plural(int $count, array $words)
|
|
||||||
{
|
|
||||||
$cases = [2, 0, 1, 1, 1, 2];
|
|
||||||
return $words[
|
|
||||||
$count % 100 > 4 && $count % 100 < 20 ? 2 : $cases[min($count % 10, 5)]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
export type WordForms = [string, string, string];
|
|
||||||
|
|
||||||
export const plural = (count: number, words: WordForms): string => {
|
|
||||||
const cases = [2, 0, 1, 1, 1, 2];
|
|
||||||
return words[
|
|
||||||
count % 100 > 4 && count % 100 < 20 ? 2 : cases[Math.min(count % 10, 5)]
|
|
||||||
];
|
|
||||||
};
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
type Split<S extends string, D extends string> = S extends ''
|
|
||||||
? []
|
|
||||||
: S extends `${infer T}${D}${infer U}`
|
|
||||||
? [T, ...Split<U, D>]
|
|
||||||
: [S];
|
|
||||||
|
|
||||||
type UnwrapNumbers<T extends string | string[] | number | number[]> = T extends number | number[]
|
|
||||||
? T
|
|
||||||
: T extends string
|
|
||||||
? T extends `${infer N extends number}`
|
|
||||||
? N
|
|
||||||
: never
|
|
||||||
: T extends [infer H extends string, ...infer T extends string[]]
|
|
||||||
? UnwrapNumbers<H> extends never
|
|
||||||
? never
|
|
||||||
: [UnwrapNumbers<H>, ...UnwrapNumbers<T>]
|
|
||||||
: [];
|
|
||||||
|
|
||||||
type IPv4Octets = [number, number, number, number];
|
|
||||||
type IPv6Octets = string[];
|
|
||||||
|
|
||||||
type IPv4<CIDR extends string> = Split<CIDR, '/'> extends [
|
|
||||||
infer IP extends string,
|
|
||||||
infer SUBNET extends string,
|
|
||||||
]
|
|
||||||
? UnwrapNumbers<Split<IP, '.'>> extends infer OCTETS
|
|
||||||
? OCTETS extends never
|
|
||||||
? never
|
|
||||||
: OCTETS extends IPv4Octets
|
|
||||||
? UnwrapNumbers<SUBNET> extends never
|
|
||||||
? never
|
|
||||||
: CIDR
|
|
||||||
: never
|
|
||||||
: never
|
|
||||||
: never;
|
|
||||||
|
|
||||||
type IPv6<CIDR extends string> = Split<CIDR, '/'> extends [
|
|
||||||
infer IP extends string,
|
|
||||||
infer SUBNET extends string,
|
|
||||||
]
|
|
||||||
? Split<IP, ':'> extends IPv6Octets
|
|
||||||
? UnwrapNumbers<SUBNET> extends never
|
|
||||||
? never
|
|
||||||
: CIDR
|
|
||||||
: never
|
|
||||||
: never;
|
|
||||||
|
|
||||||
type Test_1 = IPv4<'0.0.0.0/0'>;
|
|
||||||
type Test_2 = IPv4<'255.255.255.255/32'>;
|
|
||||||
type Test_3 = IPv4<'127.0.0.0.1/32'>;
|
|
||||||
type Test_4 = IPv4<'a'>;
|
|
||||||
type Test_5 = IPv4<'1.1.1.a/32'>;
|
|
||||||
type Test_6 = IPv4<'1.1.1.1'>;
|
|
||||||
type Test_7 = IPv4<'1.1.1.1/'>;
|
|
||||||
type Test_8 = IPv4<'1.1.1.1/a'>;
|
|
||||||
|
|
||||||
type Test_9 = IPv6<'::1/0'>;
|
|
||||||
type Test_10 = IPv6<'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'>;
|
|
||||||
type Test_11 = IPv6<'::1/128'>;
|
|
||||||
type Test_12 = IPv6<'a'>;
|
|
||||||
type Test_13 = IPv6<'1:1:1:1:1:1:1:1/128'>;
|
|
||||||
type Test_14 = IPv6<'1:1:1:1:1:1:1:1'>;
|
|
||||||
type Test_15 = IPv6<'1:1:1:1:1:1:1:1/'>;
|
|
||||||
type Test_16 = IPv6<'1:1:1:1:1:1:1:1/a'>;
|
|
||||||
|
|
||||||
// TODO: fully-typed ipv6 (unwrap hex, full and abbreviated address representations)
|
|
||||||
Reference in New Issue
Block a user