uz
Feedback
ToCode

ToCode

Kanalga Telegramโ€™da oโ€˜tish

ื˜ื™ืคื™ื ืงืฆืจื™ื ืœืžืชื›ื ืชื™ื ืžืืช ื™ื ื•ืŸ ืคืจืง

Ko'proq ko'rsatish
1 419
Obunachilar
Ma'lumot yo'q24 soatlar
Ma'lumot yo'q7 kunlar
-530 kunlar
Postlar arxiv
ToCode
1 419
ื–ืžืŸ ืœื™ืžื•ื“ ืืจื•ืš ื‘ื‘ื™ืช ืกืคืจ ืœื™ืžื“ื• ืื•ืชื™ ืฉื™ืœื“ื™ื ื—ื›ืžื™ื ืœื•ืžื“ื™ื ื“ื‘ืจื™ื ืžื”ืจ ื™ื•ืชืจ. ืฉืขื“ื™ืฃ ืœืœืžื•ื“ ืืช ื”ื—ื•ืžืจ ื‘ืคื—ื•ืช ื–ืžืŸ ื•ืื ืฉื ื™ ื™ืœื“ื™ื ืžืงื‘ืœื™ื ืืช ืื•ืชื• ืฆื™ื•ืŸ ืื– ื–ื” ืฉืœืžื“ ืคื—ื•ืช ื”ื•ื ื”ื™ื•ืชืจ ื—ื›ื. ื”ื—ื™ื™ื ื”ืืžื™ืชื™ื™ื ืœื™ืžื“ื• ืื•ืชื™ ืืช ื”ื”ื™ืคืš. ื”ื™ื•ื ืื ื™ ืžื‘ื™ืŸ ืฉืžื” ืฉืื ื—ื ื• ืฆืจื™ื›ื™ื ื–ื” ืืช ื”ื™ื›ื•ืœืช ืœืœืžื•ื“ ืžืฉื”ื• ืœืื•ืจืš ื–ืžืŸ ืืจื•ืš. ืืช ื”ื™ื›ื•ืœืช ืœื”ืชืจื›ื–, ืœื”ืขืžื™ืง, ืœืฉืื•ืœ ืขื•ื“ ืฉืืœื•ืช. ื‘ื”ื™ื ืชืŸ ืžืกืœื•ืœ ืžืกืคื™ืง ืืจื•ืš ื”ืชืžื“ื” ืžื ืฆื—ืช ืžื”ื™ืจื•ืช ื‘ื›ืœ ืคืขื.

ToCode
1 419
ื”ื›ืœ ื‘ืกื“ืจ ื˜ื™ื™ืคืกืงืจื™ืคื˜? ื”ืงื•ื“ ื”ื‘ื ื‘ื˜ื™ื™ืคืกืงืจื™ืคื˜ ื”ืฆืœื™ื— ืœื‘ืœื‘ืœ ืื•ืชื™ ืœืจื’ืข-
type MyItem = {type: 'a', url: string, id: number}

function go(item: MyItem) {}

const f = {type: 'a', url: 'url', id: 0}
go(f)
ื”ื•ื ืœื ืžืชืงืžืคืœ. ื”ืคื•ื ืงืฆื™ื” ืœื ืžื•ื›ื ื” ืœืงื‘ืœ ืืช f ื›ื™ ื”ื™ื ื˜ื•ืขื ืช ืฉื”ื•ื ืžื˜ื™ืคื•ืก ืœื ืžืชืื™ื. ื”ื›ืœ ื‘ืกื“ืจ ื˜ื™ื™ืคืกืงืจื™ืคื˜? ืชืกืชื›ืœ ื‘ื˜ื™ืคื•ืก MyItem, ื–ื” ื‘ื“ื™ื•ืง ืžืชืื™ื. ื”ืืžืช ืฉื˜ื™ื™ืคืกืงืจื™ืคื˜ ืฆื•ื“ืง (ืœืคื—ื•ืช ื—ืœืงื™ืช). ื”ื“ืจืš ื‘ื” ื˜ื™ื™ืคืกืงืจื™ืคื˜ ืขื•ื‘ื“ ื›ืฉื™ืฉ ืœื™ ื”ืฉืžื” ืฉืœ ืื•ื‘ื™ืงื˜ ืœืžืฉืชื ื” ื”ื™ื ืœื ืกื•ืช ืœื”ืกื™ืง ืื•ื˜ื•ืžื˜ื™ืช ืžื” ื”ื˜ื™ืคื•ืก ื”ื›ื™ ื”ื’ื™ื•ื ื™ ืฉืœ ืื•ืชื• ืžืฉืชื ื”, ื•ืœืคื™ ื”ื˜ื™ืคื•ืก ื”ื–ื” ื”ื•ื ืžื’ื‘ื™ืœ ืืช ื”ืคืขื•ืœื•ืช ื”ื‘ืื•ืช ืฉืืคืฉืจ ืœืขืฉื•ืช ืขื ืื•ืชื• ืžืฉืชื ื”. ื‘ืžืงืจื” ืฉืœ f ื”ื˜ื™ืคื•ืก ืฉื˜ื™ื™ืคืกืงืจื™ืคื˜ ื”ืกื™ืง ื”ื•ื:
const f: {
    type: string;
    url: string;
    id: number;
}
ื›ืœื•ืžืจ ื” type ื”ื•ื ืžืกื•ื’ string ื•ืœื ืžื”ืกื•ื’ ื”ืกืคืฆื™ืคื™ 'a'. ืžื‘ื—ื™ื ืช ื˜ื™ื™ืคืกืงืจื™ืคื˜ ืžื•ืชืจ ืœืฉื ื•ืช ืืช ื” type ืœืขืจืš ืื—ืจ, ื›ืœื•ืžืจ ื”ืงื•ื“ ื”ื‘ื ื›ืŸ ืžืชืงืžืคืœ:
type MyItem = {type: 'a', url: string, id: number}

function go(item: MyItem) {}

const f = {type: 'a', url: 'url', id: 0}
f.type = 'b';
ื›ืฉื˜ื™ื™ืคืกืงืจื™ืคื˜ ืจื•ืื” ืืช ื”ืงืจื™ืื”:
go(f)
ื”ื•ื ืžืกืชื›ืœ ืจืง ืขืœ ื”ื˜ื™ืคื•ืก ืฉืœ f ื•ืขืœ ื”ื˜ื™ืคื•ืก ืฉื”ืคื•ื ืงืฆื™ื” ืฆืจื™ื›ื” ืœืงื‘ืœ ื•ืžื‘ื™ืŸ ืฉืื™ืŸ ื”ืชืืžื”. ื˜ื™ื™ืคืกืงืจื™ืคื˜ ืœื ื™ื›ื•ืœ ืœื”ืชื—ื™ื™ื‘ ืฉืืฃ ืื—ื“ ืœื ืฉื™ื ื” ืืช ื”ืขืจืš ืฉืœ type ื›ื™ ืžื‘ื—ื™ื ืชื• ืžื•ืชืจ ืœืฉื ื•ืช ืืช ื”ืขืจืš ืฉื. ืœื›ืŸ ื”ื•ื ื’ื ืœื ื™ื›ื•ืœ ืœื”ืชื—ื™ื™ื‘ ืฉืžื” ืฉื ืžืฆื ื›ืจื’ืข ื‘ืžืฉืชื ื” f ื‘ืืžืช ืžืชืื™ื ืœื—ืชื™ืžื” ืฉืœ ื”ืคื•ื ืงืฆื™ื”. ืื™ืš ืคื•ืชืจื™ื ืืช ื–ื”? ืื– ืžืกืชื‘ืจ ืฉื™ืฉ ื›ืžื” ื“ืจื›ื™ื - ืงื•ื“ื ื›ืœ ืืคืฉืจ ืœื”ื’ื™ื“ ืœื˜ื™ื™ืคืกืงืจื™ืคื˜ ื‘ืฆื•ืจื” ืžืคื•ืจืฉืช ืžื” ื”ื˜ื™ืคื•ืก ืฉืœ f:
type MyItem = {type: 'a', url: string, id: number}

function go(item: MyItem) {}

const f: MyItem = {type: 'a', url: 'url', id: 0}
ืขื›ืฉื™ื• ืืคืฉืจ ื™ื”ื™ื” ืœื”ืขื‘ื™ืจ ืื•ืชื• ืœืคื•ื ืงืฆื™ื” go ื•ืื™ ืืคืฉืจ ื™ื”ื™ื” ืœืฉื ื•ืช ืืช ื”ืขืจืš ืฉืœ f.type. ืขื•ื“ ืื•ืคืฆื™ื” ื”ื™ื ืœื”ื’ื“ื™ืจ ืฉ type ื”ื•ื ืงื‘ื•ืข ื‘ืชื•ืš ื”ื’ื“ืจืช ื”ืื•ื‘ื™ืงื˜:
const f = {type: 'a' as const, url: 'url', id: 0}
ื•ื“ืจืš ืฉืœื™ืฉื™ืช ืœืงื‘ืœ ืืช ืื•ืชื• ื˜ื™ืคื•ืก ื”ื™ื ืœื”ื’ื“ื™ืจ ืืช type ืžืžืฉ ืœื”ื™ื•ืช a:
const f = {type: 'a' as 'a', url: 'url', id: 0}
ืžื›ื™ืจื™ื ืจืขื™ื•ื ื•ืช ื ื•ืกืคื™ื? ืฉืชืคื• ื‘ืชื’ื•ื‘ื•ืช ืืฉืžื— ืœืฉืžื•ืข.

ToCode
1 419
ืžื” map ืžื—ื–ื™ืจื” ืขื•ื“ ื“ืจืš ืœื”ืกืชื›ืœ ืขืœ ื”ื”ื‘ื“ืœ ื‘ื™ืŸ ืชื›ื ื•ืช ืžื•ื ื—ื” ืขืฆืžื™ื ืœืชื›ื ื•ืช ืคื•ื ืงืฆื™ื•ื ืืœื™ ื”ื™ื ืœื”ืกืชื›ืœ ืขืœ ืคื•ื ืงืฆื™ื•ืช ื•ืขืจื›ื™ ื”ื”ื—ื–ืจ ืฉืœื”ืŸ. ื ื™ืงื— ืืช ื”ืคื•ื ืงืฆื™ื” map ืœื“ื•ื’ืžื” ื•ื ืฉื•ื•ื” - ืกืงืืœื”, ืฉื”ื™ื ืฉืคื” ืžื•ื ื—ื™ืช ืขืฆืžื™ื, ืชื’ื“ื™ืจ ืœื›ืœ Collection ืคื•ื ืงืฆื™ื™ืช map ืฉื•ื ื” ืฉืžื—ื–ื™ืจื” Collection ื—ื“ืฉ ืžืื•ืชื• ื”ืกื•ื’. ื‘ื’ืœืœ ื–ื” ื›ืฉืื ื™ ืžืจื™ืฅ map ืขืœ ืงื‘ื•ืฆื” ืื ื™ ืžืงื‘ืœ ื—ื–ืจื” ืงื‘ื•ืฆื”:
scala> Set(1, 2, 3).map(_ * 2)
val res1: Set[Int] = Set(2, 4, 6)

scala> List(1, 2, 3).map(_ * 2)
val res4: List[Int] = List(2, 4, 6)
ืงืœื•ื–'ืจ ืœืขื•ืžืชื” ืฉืžื” ืืช ื”ื“ื’ืฉ ืขืœ ื”ืคื•ื ืงืฆื™ื” ื•ืœื›ืŸ ื”ืคืขืœื” ืฉืœ map ืขืœ ื›ืœ ื“ื‘ืจ ืžื—ื–ื™ืจื” ืชืžื™ื“ LazySeq:
user=> (type (map (partial * 2) #{1 2 3}))
clojure.lang.LazySeq
user=> (type (map (partial * 2) [1 2 3]))
clojure.lang.LazySeq
ื• JavaScript ืžืกื›ื™ืžื” ืœื”ื’ื“ื™ืจ map ืจืง ืขืœ ืจืฉื™ืžื” ื•ืœื›ืŸ:
new Set([1, 2, 3]).map(i => i * 2)
TypeError: new Set([1, 2, 3]).map is not a function. (In 'new Set([1, 2, 3]).map(i => i * 2)', 'new Set([1, 2, 3]).map' is undefined)
ืžื” ืขื“ื™ืฃ? ืœื ื ืขื™ื ืœื”ื’ื™ื“ ืื‘ืœ ืื ื™ ืžืฆืœื™ื— ืœื˜ืขื•ืช ื‘ื›ืœ ื”ืฉืคื•ืช. ื”ื“ื‘ืจ ื”ื—ืฉื•ื‘ ื”ื•ื ืชืžื™ื“ ืœื–ื›ื•ืจ ื‘ืื™ื–ื” ืฉืคื” ืื ื—ื ื• ื•ืžื” ื”ืžืืคื™ื™ื ื™ื ืฉืœ ืื•ืชื” ืฉืคื”. ืืคื™ืœื• (ื•ืื•ืœื™ ื‘ืžื™ื•ื—ื“) ื›ืฉืœืคื•ื ืงืฆื™ื•ืช ื™ืฉ ืืช ืื•ืชื• ืฉื. ื .ื‘. ื•ืžื” ืžื—ื–ื™ืจ ื”ืงื•ื“ ื”ื‘ื ื‘ืจื•ื‘ื™? ื ืกื• ืœื‘ื“ื•ืง ื•ืชืจืื• ืื ื”ื‘ื ืชื ืœืžื”:
3.1.1 :002 > [1, 2, 3].map { _ * 2 }

ToCode
1 419
ืื•ืคื˜ื™ืžื™ื–ืฆื™ื™ืช ื–ื ื‘ ื”ืจืงื•ืจืกื™ื” ื‘ JavaScript ื‘ 2024 ืœืคื ื™ 6 ืฉื ื™ื ื›ืชื‘ืชื™ ืขืœ ืื•ืคื˜ื™ืžื™ื–ืฆื™ื™ืช ื–ื ื‘ ื”ืจืงื•ืจืกื™ื” ื‘ื“ืคื“ืคื ื™ื: https://www.tocode.co.il/blog/2018-09-javascript-tco ืžืื– ื”ืจื‘ื” ืงืจื” ื‘ื“ืคื“ืคืŸ ืื‘ืœ ื“ื•ื•ืงื ื”ืคื™ืฆ'ืจ ื”ื–ื” ื ืฉืืจ ืžืื—ื•ืจ. ืกืคืืจื™, ื›ืจื•ื ื•ื’ื ืคื™ื™ืจืคื•ืงืก ืœื ืžืฆืœื™ื—ื™ื ืœื—ืฉื‘ ืจืงื•ืจืกื™ื‘ื™ืช ืžืกืคืจื™ื ื’ื“ื•ืœื™ื. ืื‘ืœ ื ืงื•ื“ืช ืื•ืจ ืื—ืช ื›ืŸ ื”ืฆื˜ืจืคื” ื‘ืขื•ืœื ืฉืœ JavaScript ื‘ืฆื“ ืฉืจืช ืžื”ื›ื™ื•ื•ืŸ ืฉืœ bun (ื ื•ื“ ื•ื“ื™ื ื•, ื›ืžื• ื”ื“ืคื“ืคื ื™ื ืขื“ื™ื™ืŸ ืœื ืชื•ืžื›ื™ื ื‘ืื•ืคื˜ื™ืžื™ื–ืฆื™ื” ื–ื•). ื”ื ื” ื”ืชื•ื›ื ื™ืช:
function factors_of(number, i=2) {
    if (number < i) {
          return [];
        }
    
    if (number % i === 0) {
          return [i, ...factors_of(number / i, i)];
        }
    
    return factors_of(number, i+1);
}

console.log(factors_of(909090909090909090909090));
ื•ื”ืจืฆื” ื‘ืฆื“ ืฉืจืช ื‘ node:
node a.js
/Users/ynonp/tmp/a.js:1
function factors_of(number, i=2) {
                   ^

RangeError: Maximum call stack size exceeded
    at factors_of (/Users/ynonp/tmp/a.js:1:20)
    at factors_of (/Users/ynonp/tmp/a.js:10:12)
    at factors_of (/Users/ynonp/tmp/a.js:10:12)
    at factors_of (/Users/ynonp/tmp/a.js:10:12)
    at factors_of (/Users/ynonp/tmp/a.js:10:12)
    at factors_of (/Users/ynonp/tmp/a.js:10:12)
    at factors_of (/Users/ynonp/tmp/a.js:10:12)
    at factors_of (/Users/ynonp/tmp/a.js:10:12)
    at factors_of (/Users/ynonp/tmp/a.js:10:12)
    at factors_of (/Users/ynonp/tmp/a.js:10:12)

Node.js v21.7.1
ื‘ Deno:
deno run a.js
error: Uncaught (in promise) RangeError: Maximum call stack size exceeded
function factors_of(number, i=2) {
                   ^
    at factors_of (file:///Users/ynonp/tmp/a.js:1:20)
    at factors_of (file:///Users/ynonp/tmp/a.js:10:12)
    at factors_of (file:///Users/ynonp/tmp/a.js:10:12)
    at factors_of (file:///Users/ynonp/tmp/a.js:10:12)
    at factors_of (file:///Users/ynonp/tmp/a.js:10:12)
    at factors_of (file:///Users/ynonp/tmp/a.js:10:12)
    at factors_of (file:///Users/ynonp/tmp/a.js:10:12)
    at factors_of (file:///Users/ynonp/tmp/a.js:10:12)
    at factors_of (file:///Users/ynonp/tmp/a.js:10:12)
    at factors_of (file:///Users/ynonp/tmp/a.js:10:12)
ื•ืจืง bun ืžืคืชื™ืข ืœื˜ื•ื‘ื”:
$ bun a.js
[
  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  71, 101, 251, 401, 9384251
]

ToCode
1 419
ืœืžื” ื‘ื ื™ืช ืืช ื–ื” ื›ื›ื”? ื ืชื•ื ื” ืงื•ืžืคื•ื ื ื˜ืช ืจื™ืืงื˜:
function ItemData() {
    const { id } = useParams();
    const { data, error, isLoading } = useSWR('/api/user', fetcher);
    
    if (isLoading) return <p>Loading...</p>;
    if (error) return <p>Error</p>;
    
    return <ItemView item={data} />
}
ื”ืงื•ืžืคื•ื ื ื˜ื” ืœื•ืงื—ืช ืืช ื”ืคืจืžื˜ืจ id ืžื”ื’ื“ืจื•ืช ื”ื ืชื™ื‘, ืคื•ื ื” ืœืฉืจืช ื›ื“ื™ ืœืžืฉื•ืš ืืช ื”ืžื™ื“ืข ืขืœ ื”ืคืจื™ื˜ ื•ืื– ืžืฆื™ื’ื” ืืช ื”ืžื™ื“ืข ื‘ ItemView. ื”ืชืฆื•ื’ื” ื‘ืงื•ืžืคื•ื ื ื˜ื” ื ืคืจื“ืช ื›ื“ื™ ืฉืืคืฉืจ ื™ื”ื™ื” ืœื‘ื“ื•ืง ืื•ืชื” ื‘ืœื™ ืงืฉืจ ืœืžืฉื™ื›ืช ื”ืžื™ื“ืข ื•ื’ื ื–ื” ื™ื•ืชืจ ื ื•ื— ืœืชื—ื–ืง ื›ื›ื” ืืช ื”ืงื•ื“, ืื‘ืœ ืœืžื” ืœืคื ื•ืช ืœืฉืจืช ืจืง ืื—ืจื™ ืฉื”ืงื•ืžืคื•ื ื ื˜ื” ืžืชืจื ื“ืจืช ื›ื“ื™ ืœืžืฉื•ืš ืืช ื”ืžื™ื“ืข? ืชืฉื•ื‘ื” 1 - ื›ื™ ื–ื” ื”ื›ื™ ืžื”ื™ืจ ืคื ื™ื” ืฉื ื™ื” ืœืฉืจืช? ืžื” ืคืชืื•ื, ืคื ื™ืชื™ ืœืฉืจืช ืจืง ืคืขื ืื—ืช. ื” HTML ื•ื” JavaScript ืฉืžื’ื™ืขื™ื ืœืœืงื•ื— ื ืฉืœื—ื™ื ืž CDN ื•ืœื ืžื”ืฉืจืช ืฉืœื™. ืจืง ืื—ืจื™ ื˜ืขื™ื ืช ื”ืขืžื•ื“ ื”ืžืขืจื›ืช ืคื•ื ื” ืœืฉืจืช ืฉืœื™ ื›ื“ื™ ืœืžืฉื•ืš ืืช ื›ืœ ื”ืžื™ื“ืข ื”ืจืœื•ื•ื ื˜ื™ ื•ืœื”ืฆื™ื’ ืืช ื”ืขืžื•ื“. ืžื” ืืคืฉืจ ืœืขืฉื•ืช ืื—ืจืช? ื”ืืžืช ืฉื˜ื•ื‘ ืฉืฉืืœืช. ืื ืจืฉื™ืžืช ื”ืคืจื™ื˜ื™ื ื™ื“ื•ืขื” ืžืจืืฉ ืืคืฉืจ ื”ื™ื” ืœื‘ื ื•ืช ื‘ Offline ืขืžื•ื“ื™ HTML ืฉื•ื ื™ื ืขื‘ื•ืจ ื›ืœ id ื•ืœืฉืžื•ืจ ืืช ื”ื›ืœ ื‘ CDN, ื•ื›ืš ื”ื“ืคื“ืคืŸ ื”ื™ื” ื™ื›ื•ืœ ืœื”ืฆื™ื’ ืืช ื”ืžื™ื“ืข ื”ื›ื™ ืžื”ืจ - ืžื™ื“ ืื™ืš ืฉื”ื•ื ืžืงื‘ืœ ืืช ื”ืขืžื•ื“ ืืคื™ืœื• ื‘ืœื™ ืœื”ืจื™ืฅ ืงื•ื“ ืจื™ืืงื˜. ืชื›ืœ'ืก ื ืงืกื˜ ื™ื•ื“ืข ืœืขืฉื•ืช ืืช ื–ื” ืื•ื˜ื•ืžื˜ื™ืช. ืื ื”ืจืฉื™ืžื” ื“ื™ื ืžื™ืช ืืคืฉืจ ืœื”ืฉืชืžืฉ ื‘ Server Components ื›ื“ื™ ืœืžืฉื•ืš ืืช ื›ืœ ื”ืžื™ื“ืข ืžื‘ืกื™ืก ื”ื ืชื•ื ื™ื ืœืคื ื™ ืฉืฉื•ืœื—ื™ื ืืช ื”ืขืžื•ื“ ืœืœืงื•ื— ื•ื›ืš ืœืฆืžืฆื ืงืจื™ืื•ืช. ื‘ืืฆืช ื™ื”ื™ื” ืžืขื ื™ื™ืŸ ืœื‘ื“ื•ืง ืžื‘ื—ื™ื ืช ื‘ื™ืฆื•ืขื™ื ืื™ื–ื” ื’ื™ืฉื” ื ื•ืชื ืช ืชื•ืฆืื•ืช ื˜ื•ื‘ื•ืช ื™ื•ืชืจ. ืชืฉื•ื‘ื” 2 - ื›ื™ ื–ื” ืœื ื”ื™ื” ืžืกืคื™ืง ื—ืฉื•ื‘ ืคื ื™ื” ืฉื ื™ื” ืœืฉืจืช? ื ื• ื‘ืกื“ืจ ื™ืฉ ืœื™ ืขื•ื“ 5 ืžืื™ืคื” ืฉื–ืืช ื‘ืื”. ืœืžื™ ืื›ืคืช ื›ืžื” ืคื ื™ื•ืช ืœืฉืจืช ืืชื” ืฉื•ืœื— ื‘ืฉื‘ื™ืœ ืœื”ืฆื™ื’ ืืช ื”ืชื•ื›ืŸ? ืื ื™ ืฉื•ืžืจ ื‘ DB ืกื˜ื˜ื™ืกื˜ื™ืงื” ืฉืžืจืื” ืฉืœ 95% ืžื”ืœืงื•ื—ื•ืช ื”ืขืžื•ื“ ื ื˜ืขืŸ ืชื•ืš ืคื—ื•ืช ืžืฉื ื™ื” ื•ื–ื” ื›ืœ ืžื” ืฉื—ืฉื•ื‘. ื›ืœ ืขื•ื“ ืื ื—ื ื• ืœื ื—ื•ืจื’ื™ื ืžืชืงืฆื™ื‘ ื”ื‘ื™ืฆื•ืขื™ื ืฉืœื ื• ืขื“ื™ืฃ ืœื”ืชืžืงื“ ื‘ืคื™ืฆ'ืจื™ื ื•ืœื ื‘ืื•ืคื˜ื™ืžื™ื–ืฆื™ื•ืช. ืชืฉื•ื‘ื” 3 - ื›ื™ ื–ื” ืžื” ืฉื”ื™ื” ื›ืชื•ื‘ ื‘ืชื™ืขื•ื“ ื›ืœ ืžื™ ืฉื›ื•ืชื‘ ืจื™ืืงื˜ ื™ื•ื“ืข ืฉ react-query ื• swr ื”ืŸ ื”ื“ืจืš ื”ื›ื™ ื˜ื•ื‘ื” ืœืžืฉื•ืš ืžื™ื“ืข ืžื”ืฉืจืช. ืžื” ืจืฆื™ืช ืฉืื›ืชื•ื‘ useEffect ืฉื? ื—ื•ืฅ ืžื–ื” ื”ื›ืœ ืขื•ื‘ื“ ืื– ืœื ื ื•ื’ืขื™ื. ืชืฉื•ื‘ื” ื˜ื•ื‘ื” ืœ"ืœืžื” ื‘ื ื™ืช ืืช ื–ื” ื›ื›ื”" ืฆืจื™ื›ื” ืœืคืชื•ื— ื“ื™ื•ืŸ. ืฆืจื™ื›ื” ืœื—ืฉื•ืฃ ืขื•ื“ ืื•ืคืฆื™ื•ืช ื•ืืช ืžืขืจืš ื”ืฉื™ืงื•ืœื™ื ืฉื”ื•ื‘ื™ืœ ืœื‘ื—ื™ืจื” ื‘ื“ืจืš ืžืกื•ื™ืžืช. ืื ืื™ืŸ ืœื›ื ืขื“ื™ื™ืŸ ืชืฉื•ื‘ื” ื˜ื•ื‘ื” ื–ื” ืื•ืœื™ ื–ืžืŸ ื˜ื•ื‘ ืœื”ืชื—ื™ืœ ืœื—ืคืฉ.

ToCode
1 419
ืฉืœื•ืฉื” ื™ืชืจื•ื ื•ืช ืฉืœ ื ื™ื”ื•ืœ ื”ืจืฉืื•ืช ืžื‘ื•ืกืก Policy ื ื™ื”ื•ืœ ื”ืจืฉืื•ืช ื‘ืžืขืจื›ืช ื–ื” ื”ืžื ื’ื ื•ืŸ ืฉืžืืคืฉืจ ืœื ื• ืžืจื’ืข ืฉืžืฉืชืžืฉ ื”ืชื—ื‘ืจ ืœื”ื‘ื™ืŸ ืžื” ืžื•ืชืจ ืœืื•ืชื• ืžืฉืชืžืฉ ืœืขืฉื•ืช. ื‘ืื ื’ืœื™ืช ื–ื” ื ืงืจื Authorization ื•ื‘ื“ืจืš ื›ืœืœ ืื ื—ื ื• ืžืคืจื™ื“ื™ื ืืช ืžื ื’ื ื•ืŸ ื ื™ื”ื•ืœ ื”ื”ืจืฉืื•ืช ืžืžื ื’ื ื•ืŸ ื”ื”ื–ื“ื”ื•ืช (Authentication). ื”ื”ื–ื“ื”ื•ืช ืžืืคืฉืจืช ืœื™ ืœื”ื’ื™ื“ ืฉืžื™ ืฉื ื›ื ืก ื”ืจื’ืข ื”ื•ื ืžืฉืชืžืฉ X ื•ื ื™ื”ื•ืœ ื”ื”ืจืฉืื•ืช ื–ื” ืžื” ืฉืžืืคืฉืจ ืœื™ ืœื”ื’ื™ื“ ืฉืœืžืฉืชืžืฉ X ืžื•ืชืจ ืœื”ื™ื›ื ืก ืœื“ืฃ ืžืกื•ื™ื. ื‘ืžื ื’ื ื•ืŸ ื ื™ื”ื•ืœ ื”ื”ืจืฉืื•ืช ืื ื—ื ื• ืžื•ืฆืื™ื ืฉืชื™ ื’ื™ืฉื•ืช ืžืจื›ื–ื™ื•ืช (ืขื ืกืคืจื™ื•ืช ืงื•ื“ ืชื•ืืžื•ืช). ื”ื’ื™ืฉื” ื”ืจืืฉื•ื ื” ื”ื™ื ื ื™ื”ื•ืœ ื”ืจืฉืื•ืช ืžื‘ื•ืกืก ืžืฉืชืžืฉ. ืคื” ื™ืฉ ืœื ื• ื‘ Rails ืืช cancancan ื•ื‘ JavaScript/Typescript ืืช casl. ื‘ื’ื™ืฉื” ื–ืืช ืื ื—ื ื• ืžืชื—ื™ืœื™ื ืืช ื”ืชื•ื›ื ื™ืช ื‘ืœืงื—ืช ืื•ื‘ื™ืงื˜ ืžืฉืชืžืฉ ื•"ืœื”ื“ื‘ื™ืง" ืœื• ื”ืจืฉืื•ืช:
import { defineAbility } from '@casl/ability';

export default (user) => defineAbility((can) => {
  can('read', 'Article');

  if (user.isLoggedIn) {
    can('update', 'Article', { authorId: user.id });
    can('create', 'Comment');
    can('update', 'Comment', { authorId: user.id });
  }
});
ื”ืจื‘ื” ืคืขืžื™ื ืื ื™ ืžื—ืœืง ืืช ืงื˜ืข ื”ืงื•ื“ ื”ื–ื” ืœืคื•ื ืงืฆื™ื•ืช ื•ืชื”ื™ื” ืœื™ ืคื•ื ืงืฆื™ื” ืื—ืช ืฉืžื˜ืคืœืช ื‘ืžืฉืชืžืฉ ืžืกื•ื’ "ื’ื•ืœืฉ ืจื’ื™ืœ" ืคื•ื ืงืฆื™ื” ืื—ืจืช ืœ"ื’ื•ืœืฉ ืžื—ื•ื‘ืจ" ืคื•ื ืงืฆื™ื” ืฉืœื™ืฉื™ืช ืœ"ืžื ื•ื™" ื•ืจื‘ื™ืขื™ืช ืœ"ืžื ื”ืœ ื”ืืชืจ". ื‘ื›ืœ ืคื•ื ืงืฆื™ื” ืื ื™ ืžื“ื‘ื™ืง ืœืžืฉืชืžืฉ ืืช ื”ื”ืจืฉืื•ืช ื”ืžืชืื™ืžื•ืช. ืคื” ื‘ืืชืจ ืœืžืฉืœ ืื ื™ ืžืฉืชืžืฉ ื‘ืกืคืจื™ื” ื›ื–ืืช ื‘ืงื•ื“ ืจื™ื™ืœืก ื•ื™ืฉ ืœื™ ื”ืจืฉืื•ืช ื›ืžื•:
def guest_user(user)
  can :read, BlogPost do |post|
    post.published_at <= Time.now
  end

  can :read, Lesson, free: true
end
ื’ื™ืฉื” ื›ื–ืืช ืขื•ื‘ื“ืช ืžืื•ื“ ื˜ื•ื‘ ื‘ืชื—ื™ืœืช ื”ืคืจื•ื™ืงื˜ ืื• ื‘ืคืจื•ื™ืงื˜ื™ื ืงื˜ื ื™ื, ื›ืœ ืขื•ื“ ื›ืœ ื”ื”ืจืฉืื•ืช ื ื›ื ืกื•ืช ื‘ืงื•ื‘ืฅ ืื—ื“. ื’ื™ืฉื” ืฉื ื™ื™ื” ืœื ื™ื”ื•ืœ ื”ืจืฉืื•ืช ื”ื™ื ื ื™ื”ื•ืœ ืžื‘ื•ืกืก ืžื“ื™ื ื™ื•ืช. ื‘ื’ื™ืฉื” ื–ื• ืื ื™ ืžื’ื“ื™ืจ Policy ืœื’ื™ืฉื” ืœ"ื“ื‘ืจ" ืžืกื•ื™ื ื•ื‘ืชื•ืš ื”ืžื“ื™ื ื™ื•ืช ืื ื™ ืžื’ื“ื™ืจ ืžื™ ืจืฉืื™ ืœืขืฉื•ืช ืžื” ืขื ืื•ืชื• ื“ื‘ืจ. ื–ืืช ื”ื’ื™ืฉื” ืฉืื ื—ื ื• ืคื•ื’ืฉื™ื ื‘ืกืคืจื™ื•ืช ืจื™ื™ืœืก ื›ืžื• pundit ื• action_policy, ืคืื ื“ื™ื˜ ื’ื ื–ืžื™ื ื” ื‘ JavaScript. ื”ื ื” ืงื˜ืข ืžืชื•ืš ื”ืชื™ืขื•ื“ ืฉืœ action_policy ื›ื“ื™ ืฉื ืจืื” ืืช ื”ื”ื‘ื“ืœ:
class PostPolicy < ApplicationPolicy
  # everyone can see any post
  def show?
    true
  end

  def update?
    # \user\ is a performing subject,
    # \record\ is a target object (post we want to update)
    user.admin? || (user.id == record.user_id)
  end
end
ืื• ื‘ JavaScript ืžืชื•ืš ื”ืชื™ืขื•ื“ ืฉืœ pundit:
import { Policy } from 'pundit'

export default class PostPolicy extends Policy {
  constructor(user, record) {
    super(user, record)
    this.setup.apply(this)
  }

  edit() {
    return this.user.id === this.record.userId
  }

  destroy() {
    return this.user.isAdmin
  }
}
ืฉืœื•ืฉื” ื™ืชืจื•ื ื•ืช ืžื”ื™ืจื™ื ืฉืœ ืžื“ื™ื ื™ื•ืช ื”ืจืฉืื•ืช ืžื‘ื•ืกืกืช ืžื•ื“ืœื™ื ื”ื: 1. ื›ืœ ื”ื”ืจืฉืื•ืช ืฉืœ ืžื•ื“ืœ ืžืกื•ื™ื ืžืจื•ื›ื–ื•ืช ื‘ืžืงื•ื ืื—ื“. 2. ืืคืฉืจ ืœืฉืชืฃ Policy ื‘ื™ืŸ ื›ืžื” ืžื•ื“ืœื™ื. 3. ื ื™ื”ื•ืœ ืฉื™ื ื•ื™ื™ื - ืื ืื ื™ ืจื•ืฆื” ืœืงื‘ื•ืข ืžืžื—ืจ ืฉืชื•ื›ืŸ ืžืกื•ื’ ืžืกื•ื™ื ื›ื‘ืจ ืœื ื—ื•ืคืฉื™ ื‘ื’ื™ืฉื” ื”ืจืืฉื•ื ื” ืื ื™ ืฆืจื™ืš ืœืฉื ื•ืช ื‘ืฉื ื™ ืžืงื•ืžื•ืช (ื’ื ื‘ืคื•ื ืงืฆื™ื” ืฉืžื’ื“ื™ืจื” ื”ืจืฉืื•ืช ืœืื•ืจื—ื™ื ื•ื’ื ื‘ืคื•ื ืงืฆื™ื” ืฉืžื’ื“ื™ืจื” ื”ืจืฉืื•ืช ืœืžืฉืชืžืฉื™ื ืจืฉื•ืžื™ื). ื‘ื’ื™ืฉื” ื”ืฉื ื™ื™ื” ืžืกืคื™ืง ืœืขื“ื›ืŸ ืืช ืคื•ื ืงืฆื™ื™ืช ื”ืฆืคื™ื™ื” ื‘ Policy ืฉืžืชืื™ื ืœื“ื‘ืจ ืื•ืชื• ืื ื™ ืžื–ื™ื–.

ToCode
1 419
ื›ืžืขื˜ ืคืจื™ื“ื” ืž nodemon ื ื•ื“ืžื•ืŸ ื”ื™ื” ื—ื‘ืจ ื ืืžืŸ ื‘ืžืฉืš ื”ืจื‘ื” ืฉื ื™ื. ืžืกืคื™ืง ืงืฉื” ืœื–ื›ื•ืจ ืœืฉืžื•ืจ ืืช ื”ืงื•ื‘ืฅ ื›ืœ ืคืขื ืื—ืจื™ ืฉื™ื ื•ื™ื™ื, ื‘ื›ืชื™ื‘ืช ืืคืœื™ืงืฆื™ื™ืช ื•ื•ื‘ ืฆื“ ืฉืจืช ื‘ืืงืกืคืจืก ื‘ืœืขื“ื™ื• ื”ื™ื” ืฆืจื™ืš ื’ื ืœืกื’ื•ืจ ื•ืœืคืชื•ื— ืžื—ื“ืฉ ื™ื“ื ื™ืช ืืช ื”ืฉืจืช. ื ื•ื“ืžื•ืŸ ื ืชืŸ ืคื™ืชืจื•ืŸ ื›ืœ ื›ืš ื˜ื•ื‘ ืฉื›ื‘ืจ ืฉื›ื—ื ื• ืฉืคื™ืฆ'ืจ ื‘ืกื™ืกื™ ื›ืžื• ืœื˜ืขื•ืŸ ืžื—ื“ืฉ ืืช ื”ืžืขืจื›ืช ืื—ืจื™ ืฉืžืฉื ื™ื ืงื‘ืฆื™ื ื–ื” ืžืฉื”ื• ืฉืฆืจื™ืš ืœื”ื™ื•ืช ืžื•ื‘ื ื” ื‘ื›ืœื™ ื”ืขื‘ื•ื“ื”. ื•ื”ื ื” ื”ื’ื™ืข ื ื•ื“ 20 ื•ื”ืคืš ืืช ื›ืœ ื”ืขืกืง ืœื”ื™ืกื˜ื•ืจื™ื”. ื‘ืžืงื•ื ืœื”ืชืงื™ืŸ ื•ืœื”ืคืขื™ืœ nodemon ืื ื—ื ื• ื™ื›ื•ืœื™ื ื›ื‘ืจ ืœื›ืชื•ื‘:
node --watch ./bin/www
ื•ื›ืฉื™ื”ื™ื” ืฉื™ื ื•ื™ ืื•ื˜ื•ืžื˜ื™ืช ื ื•ื“ ื™ื˜ืขืŸ ืžื—ื“ืฉ ืืช ื”ืืคืœื™ืงืฆื™ื”. ืื– ืœืžื” ืจืง ื›ืžืขื˜? ืœืฆืขืจื™ ืžืฆื‘ watch ืฉืœ node ืขื“ื™ื™ืŸ ืœื ื™ื•ื“ืข ืœืขื‘ื•ื“ ืขื ืงื‘ืฆื™ TypeScript ื• ts-node ืœื ืžื›ื™ืจ ืขื“ื™ื™ืŸ ืืช ื”ืžืชื’ ื”ื–ื”, ืœื›ืŸ ืื ื”ืืคืœื™ืงืฆื™ื” ื”ื™ื ื‘ื˜ื™ื™ืคืกืงืจื™ืคื˜ ืื ื—ื ื• ืขื“ื™ื™ืŸ ื ืฆื˜ืจืš ืืช nodemon, ืฉืžืงืžืคืœ ืื•ื˜ื•ืžื˜ื™ืช ืืช ื”ื˜ื™ื™ืคืกืงืจื™ืคื˜ ืขื ื›ืœ ืฉื™ื ื•ื™.

ToCode
1 419
ื—ื•ื•ื™ืช ื”ืžืชื›ื ืช ื›ืŸ ื™ืฉ ืžื•ืฉื’ ื›ื–ื” ื•ืืคื™ืœื• ืขื ืจืืฉื™ ืชื™ื‘ื•ืช - DX, Developer Experience. ืงื• ื”ืžื—ืฉื‘ื” ื›ืืŸ ื”ื•ื ืฉืื ืื ื—ื ื• ื›ื•ืชื‘ื™ื ื›ืœื™ื ืฉืœืžืชื›ื ืชื™ื ื•ืœืžืชื›ื ืชื•ืช ื™ื”ื™ื” ืงืœ ืœื”ืฉืชืžืฉ ื‘ื”ื ืื– ื”ืชื•ื›ื ื•ืช ืฉืื•ืชื ืื ืฉื™ื ื™ื›ืชื‘ื• ื™ื”ื™ื• ื˜ื•ื‘ื•ืช ื™ื•ืชืจ, ืžื”ื™ืจื•ืช ื™ื•ืชืจ ื•ื‘ื˜ื•ื—ื•ืช ื™ื•ืชืจ. ืžืฆื“ ืฉื ื™ ื›ืฉืื ืฉื™ื ืฆืจื™ื›ื™ื ืœืขื‘ื•ื“ ืงืฉื” ื›ื“ื™ ืœืœืžื•ื“ ืื™ืš ืœื”ืฉืชืžืฉ "ื ื›ื•ืŸ" ื‘ื›ืœื™ ืฉืœืš ื”ื ื™ืขืฉื• ื™ื•ืชืจ ื˜ืขื•ื™ื•ืช ื•ื”ืชื•ืฆืื” (ื”ืืคืœื™ืงืฆื™ื” ืฉื”ื ื›ื•ืชื‘ื™ื) ืชื”ื™ื” ืคื—ื•ืช ื˜ื•ื‘ื”. ื“ื•ื’ืžื” ื˜ื•ื‘ื” ืœ DX ื”ื™ื ื›ืฉืื ื—ื ื• ื‘ื•ื ื™ื API. ืื ืงืœ ืœื”ืฉืชืžืฉ ื‘ API ื”ื–ื” ื•ืงืœ ืœืžืฉื•ืš ืžืžื ื• ืจืง ืืช ื”ืžื™ื“ืข ืฉื”ืžืชื›ื ืชื™ื ืฆืจื™ื›ื™ื ืื– ื”ืืคืœื™ืงืฆื™ื•ืช ืฉื™ื™ื›ืชื‘ื• ืขื ืื•ืชื• API ื™ืฆืื• ื˜ื•ื‘ื•ืช ื™ื•ืชืจ. ืื ื” API ืžื›ืจื™ื— ืืช ื”ืžืฉืชืžืฉื™ื ืœืžืฉื•ืš ื”ืจื‘ื” ื™ื•ืชืจ ืžื™ื“ืข ืžืžื” ืฉื”ื ืฆืจื™ื›ื™ื ืื– ืœืžืคืชื—ื™ื ืฉื™ืฉืชืžืฉื• ื‘ืื•ืชื• API ืœื ืชื”ื™ื” ื‘ืจื™ืจื” ื•ื”ื ื™ืืœืฆื• ืœื›ืชื•ื‘ ืžืขืจื›ื•ืช ืคื—ื•ืช ื˜ื•ื‘ื•ืช. ืื• ืื ืื ื™ ื›ื•ืชื‘ ืคืจื™ื™ืžื•ื•ืจืง ืขื ืชื™ืขื•ื“ ื˜ื•ื‘ ืื– ืžืชื›ื ืชื™ื ื™ืฉืชืžืฉื• ื‘ืคืจื™ื™ืžื•ื•ืจืง ื›ืžื• ืฉืชื›ื ื ืชื™ ื•ื”ืžืขืจื›ืช ืฉื”ื ื›ื•ืชื‘ื™ื ืชื”ื™ื” ืžื”ื™ืจื” ื™ื•ืชืจ. ืื ืื ื™ ืœื ื›ื•ืชื‘ ืชื™ืขื•ื“ ื”ื ื™ืฉืชืžืฉื• ื‘ื” ื‘ืฆื•ืจื” ืฉืœื ื—ืฉื‘ืชื™ ืขืœื™ื” ื•ื”ืชื•ืฆืื” ืชื”ื™ื” ื‘ืื’ื™ื ืžื•ื–ืจื™ื ื•ืžืขืจื›ืช ืื™ื˜ื™ืช ื•ืœื ืžืื•ื‘ื˜ื—ืช. ื”ื‘ืขื™ื” ื‘ DX ืžืชื—ื™ืœื” ื›ืฉ DX ืžืชื—ื™ืœ ืœื‘ื•ื ืขืœ ื—ืฉื‘ื•ืŸ UX, ื•ื›ืฉืื ื—ื ื• ืžื‘ืœื‘ืœื™ื ื‘ื™ืŸ ื›ืœื™ื ืœื›ืชื™ื‘ืช ืžืขืจื›ื•ืช ื˜ื•ื‘ื•ืช ืœ"ื›ืœื™ื ืฉื›ื™ืฃ ืœื ื• ืœื”ืฉืชืžืฉ ื‘ื”ื". ืคืจื™ื–ืžื” ืžืคื•ืจืกืžืช ื‘ืชื•ืจ ื” ORM ืขื ื” DX ื”ื˜ื•ื‘ ื‘ื™ื•ืชืจ ื‘ืขื•ืœื, ืื‘ืœ ื‘ืœื™ ืืคืฉืจื•ืช ืœืขืฉื•ืช JOIN ื‘ื™ืŸ ื˜ื‘ืœืื•ืช ื›ืœ ื™ื™ืฉื•ื ืฉื™ืฉืชืžืฉ ื‘ืคืจื™ื–ืžื” ื™ืฆื˜ืจืš ืœืขืฉื•ืช ื”ืจื‘ื” ื™ื•ืชืจ ืขื‘ื•ื“ื” (ื ื›ื•ืŸ ืื•ื˜ื•ืžื˜ื™ืช ื‘ืœื™ ืœืขืจื‘ ืืช ื”ืžืชื›ื ืชื™ื, ืื‘ืœ ืขื“ื™ื™ืŸ) ื•ืœื›ืŸ ื™ื™ืฉื•ืžื™ื ืจื‘ื™ื ื™ื”ื™ื• ืื™ื˜ื™ื™ื ื‘ื”ืจื‘ื” ื‘ื”ืฉื•ื•ืื” ืœื›ืืœื” ืฉื™ื™ื›ืชื‘ื• ืขื ื“ืจื™ื–ืœ. ืขื•ื“ ื“ื•ื’ืžื” ืžืคื•ืจืกืžืช ื”ื™ืชื” ืคื•ื ื’ืืค (ื•ืื—ืจื™ื” ืงื•ืจื“ื•ื‘ื”) ืฉื ืชื ื” ืœืžืคืชื—ื™ื ืืคืฉืจื•ืช ืœื›ืชื•ื‘ ืืคืœื™ืงืฆื™ื•ืช ืžื•ื‘ื™ื™ืœ ื‘ื›ืœื™ื ืฉืœ ืคื™ืชื•ื— ื•ื•ื‘ ืฉื”ื ื›ื‘ืจ ืžื›ื™ืจื™ื, ืื‘ืœ ื™ื™ืฆืจื” ืืคืœื™ืงืฆื™ื•ืช ืฉืขื‘ื“ื• ืœืื˜ ื•ื”ื™ื• ืžื•ื’ื‘ืœื•ืช ืžื‘ื—ื™ื ืช ื”ื™ื›ื•ืœื•ืช ื•ื”ืื™ื ื˜ื’ืจืฆื™ื” ืขื ื”ื˜ืœืคื•ืŸ. ื›ืฉืขื•ื‘ื“ื™ื ื‘ืฆื•ื•ืช ื”ืืชื’ืจ ื”ื•ื ื›ืคื•ืœ: ืื•ืชื ื›ืœื™ื ืฉืžืกืคืงื™ื DX ืžื”ืื’ื“ื•ืช ื”ืจื‘ื” ืคืขืžื™ื ืขื‘ืจื• ืžืกืคื™ืง ืœื™ื˜ื•ืฉ ื›ื“ื™ ืฉืœื ื ืจืื” ืืช ื”ื‘ืขื™ื•ืช ื‘ืืคืœื™ืงืฆื™ื•ืช POC ืงื˜ื ื•ืช. ืœืคืขืžื™ื ื™ืฉ ืชื—ื•ืฉื” ืฉืื•ืชื ื›ืœื™ื ื ื›ืชื‘ื• ืกืคืฆื™ืคื™ืช ืขื‘ื•ืจ ืื•ืชืŸ ืืคืœื™ืงืฆื™ื•ืช ืงื˜ื ื•ืช. ื”ืจื‘ื” ืคืขืžื™ื ื”ื—ื‘ืจื™ื ื‘ืฆื•ื•ืช ืœื ืœื”ื•ื˜ื™ื ืœื•ื•ืชืจ ืขืœ ื—ื•ื•ื™ืช ื”ืžืคืชื— ื”ืžื•ืฉืงืขืช ืžืชื•ืš ื”ืจื’ืฉื” ืฉื‘ืขื™ื•ืช ื”ื‘ื™ืฆื•ืขื™ื ื”ื ื“ืื’ื” ืฉืœ ื”ืขืชื™ื“ ืื• ืฉืื•ืœื™ ื‘ื›ืœืœ ืœื ื™ื’ื™ืขื• ืืœื™ื ื•. ืื™ืŸ ืœื™ ืคื™ืชืจื•ืŸ ืงืœ ืœืžืฆื‘ื™ื ื”ืืœื”. ื›ื›ืœืœ ื›ื›ืœ ืฉืื ื—ื ื• ืžื‘ื™ื ื™ื ื™ื•ืชืจ ื˜ื•ื‘ ืืช ื”ื›ืœื™ื ื•ืืช ื”ืžื’ื‘ืœื•ืช ื”ืžื•ื‘ื ื•ืช ืฉืœื”ื ืงืœ ืœื ื• ื™ื•ืชืจ ืœื‘ื—ื•ืจ ืืช ืื•ืชื ื›ืœื™ื ืฉืžืฉืœื‘ื™ื ื—ื•ื•ื™ืช ืžืคืชื—ื™ื ื˜ื•ื‘ื” ืขื ืžื•ืฆืจ ื˜ื•ื‘ ืœืœืงื•ื—.

ToCode
1 419
ืคื” ื›ืžืขื˜ ื”ืชื™ื™ืืฉืชื™ ืขื“ ืฉืžืฆืืชื™ ืืช ื”ืคื•ืกื˜ ื”ื–ื”: https://aymarino.github.io/polygon-area/ ืฉืžืกื‘ื™ืจ ืขืœ ื ื•ืกื—ื” ื‘ืฉื ื ื•ืกื—ืช ืฉืจื•ืš ื”ื ืขืœ ืฉืžืืคืฉืจืช ืœื—ืฉื‘ ืฉื˜ื— ืฉืœ ืคื•ืœื™ื’ื•ืŸ ืจืง ืœืคื™ ื”ืงื•ื“ืงื•ื“ื™ื ืฉืœื•. ื‘ืฉื‘ื™ืœ ืœื”ืฉืชืžืฉ ื‘ื ื•ืกื—ื” ืชื—ื™ืœื” ื”ืคื›ืชื™ ืืช ืจืฉื™ืžืช ื”ื”ื•ืจืื•ืช ืœืจืฉื™ืžื” ืฉืœ ืงื•ื“ืงื•ื“ื™ื:
def coordinates(input: Source, parseLine: (line: String) => PaintingInstruction): List[(Long, Long, Long)] =
    input
      .getLines()
      .scanLeft((0L, 0L, 0L)) { (acc, line) =>
        val (row, column, distance) = acc
        val paintingInstruction = parseLine(line)

        paintingInstruction.dir match
          case "L" => (row, column - paintingInstruction.count, distance + paintingInstruction.count)
          case "R" => (row, column + paintingInstruction.count, distance + paintingInstruction.count)
          case "U" => (row - paintingInstruction.count, column, distance + paintingInstruction.count)
          case "D" => (row + paintingInstruction.count, column, distance + paintingInstruction.count)
      }.toList
ื”ืขืจืš ื”ืฉืœื™ืฉื™ ื‘ืจืฉื™ืžื” ื”ื•ื ื”ืžืจื—ืง ื”ื›ื•ืœืœ ืฉืœ ื”ืฆื•ืจื”, ื•ื–ื” ื™ืขื–ื•ืจ ืœื ื• ื‘ื”ืžืฉืš ื”ื—ื™ืฉื•ื‘. ื›ืชื‘ืชื™ ืฉืชื™ ืคื•ื ืงืฆื™ื•ืช ืœืงืจื™ืืช ืฉื•ืจื•ืช ืœื”ืชืื™ื ืœืฉื ื™ ื—ืœืงื™ ื”ืชืจื’ื™ืœ:
  def parsePart1(line: String): PaintingInstruction =
    val lineRE = """(\w) (\d+) \((#\w+)\)""".r
    val List(d, count, color) = lineRE.findFirstMatchIn(line).get.subgroups
    PaintingInstruction(d, count.toInt, color)

  def parsePart2(line: String): PaintingInstruction =
    val lineRE = """\w \d+ \(#(\w\w\w\w\w)(\w)\)""".r
    val List(count, d) = lineRE.findFirstMatchIn(line).get.subgroups
    val distance = java.lang.Long.parseLong(count, 16)
    val direction = d match
      case "0" => "R"
      case "1" => "D"
      case "2" => "L"
      case "3" => "U"

    PaintingInstruction(direction, distance, "...")
ื•ืื– ืืช ื”ื ื•ืกื—ื” ืœืฉื˜ื— ืคื•ืœื™ื’ื•ืŸ:
  def shoelace(coordinates: List[(Long, Long, Long)]): Long =
    coordinates.zip(coordinates.tail).map { pair =>
      val ((x1, y1, d1), (x2, y2, d2)) = pair
      x1 * y2 - y1 * x2
    }
    .sum
    .abs / 2
ื–ื” ื”ืงื•ื“ ืœื—ืœืง ื”ืจืืฉื•ืŸ:
  def day18part1(): Unit =
    val coords = coordinates(Source.fromResource("day18.txt"), parsePart1)
    val distance = coords.last._3
    val area = shoelace(coords)
    val poolSize = area + distance / 2 + 1

    println(poolSize)
ื•ื–ื” ื”ื—ืœืง ื”ืฉื ื™:
  def day18part1(): Unit =
    val coords = coordinates(Source.fromResource("day18.txt"), parsePart2)
    val distance = coords.last._3
    val area = shoelace(coords)
    val poolSize = area + distance / 2 + 1

    println(poolSize)
ืื ื™ ืžื•ื“ื” ืฉื‘ืžื‘ื˜ ืจืืฉื•ืŸ ื”ืชืจื’ื™ืœ ื”ื–ื” ื ืจืื” ืœื™ ืžืฉืขืžื ื•ืœื›ืŸ ืœืงื— ืœื™ ื”ืจื‘ื” ื–ืžืŸ ืœื’ืฉืช ืืœื™ื•. ื‘ืกื•ืคื• ืฉืœ ื“ื‘ืจ ื”ื™ื” ื˜ื•ื•ื™ืกื˜ ื•ืœืžื“ืชื™ ื›ืžื” ื ื•ืกื—ืื•ืช ื—ื“ืฉื•ืช ื›ืš ืฉื™ืฆื ืžื•ืฆืœื—.

ToCode
1 419
ืคื™ืชืจื•ืŸ Advent Of Code ื™ื•ื 18 ื‘ืกืงืืœื” ืžื–ืžืŸ ืœื ื›ืชื‘ื ื• Advent Of Code ื•ื–ื• ื”ื–ื“ืžื ื•ืช ืžืฆื•ื™ื ืช ืœื”ื™ื–ื›ืจ ื•ืœื”ืชืงื“ื. ื™ืฉ ืœื ื• 25 ื—ื™ื“ื•ืช ืกืš ื”ื›ืœ ืื– ืื ื—ื ื• ืžืžืฉ ืžืชืงืจื‘ื™ื ืœืกื™ื•ื. ื‘ื•ืื• ื ืจืื” ืืช ื™ื•ื 18, ืืช ื”ื ื™ืกื™ื•ืŸ ื”ืจืืฉื•ืŸ ื”ืืจื•ืš ื•ื”ืœื ืžื•ืฆืœื— ืฉืœื™ ื•ืื– ืืช ื”ืคื™ืชืจื•ืŸ ื”ืืžื™ืชื™. ืžื” ืฆืจื™ืš ืœื—ืฉื‘ ื”ื™ื•ื ืื ื—ื ื• ื”ื•ืœื›ื™ื ืœื—ืคื•ืจ ื‘ืจื™ื›ื”. ื‘ื“ืจืš ื›ืœืœ ื›ืฉืžืฆื™ื™ืจื™ื ืžื˜ืจื™ืฆื” ื“ื•-ืžื™ืžื“ื™ืช ืื ื—ื ื• ืžื“ืžื™ื™ื ื™ื ืฉืื ื—ื ื• ืžืกืชื›ืœื™ื ืขืœ ื”ืžืฉื˜ื— ืžืœืžืขืœื”, ืื‘ืœ ื‘ืชืจื’ื™ืœ ื”ื™ื•ื ืื ื—ื ื• ืžืกืชื›ืœื™ื ืขืœ ื”ื‘ืจื™ื›ื” ืžื”ืฆื“. ื–ื” ื”ืฆื™ื•ืจ ืœื”ืžื—ืฉื”:
 #######
 #.....#
 ###...#
 ..#...#
 ..#...#
 ###.###
 #...#..
 ##..###
 .#....#
 .######
ืื™ืš ื—ื•ืคืจื™ื ืืช ื”ื‘ืจื™ื›ื” ืืชื ืฉื•ืืœื™ื? ืื™ืŸ ื‘ืขื™ื” ื–ื” ื‘ื“ื™ื•ืง ื”ืงืœื˜ ืœืคืื–ืœ. ื‘ืฉื‘ื™ืœ ืœื—ืคื•ืจ ืื ื—ื ื• ืžืงื‘ืœื™ื ืจืฉื™ืžืช ื”ื•ืจืื•ืช ืฉื ืจืื™ืช ื›ืš:
R 6 (#70c710)
D 5 (#0dc571)
L 2 (#5713f0)
D 2 (#d2c081)
R 2 (#59c680)
D 2 (#411b91)
L 5 (#8ceee2)
U 2 (#caa173)
L 1 (#1b58a2)
U 2 (#caa171)
R 2 (#7807d2)
U 3 (#a77fa3)
L 2 (#015232)
U 2 (#7a21e3)
ื”ืื•ืชื™ื•ืช R, D, L ื• U ืงื•ื‘ืขื•ืช ืœืื™ื–ื” ื›ื™ื•ื•ืŸ ืœื—ืคื•ืจ (ืฉืžืืœื”, ืœืžื˜ื”, ื™ืžื™ื ื” ืื• ืœืžืขืœื”) ื•ื”ืžืกืคืจ ืงื•ื‘ืข ื›ืžื” ืžื˜ืจ. ื ืชืขืœื ื‘ื™ื ืชื™ื™ื ืžื”ืžืกืคืจ ื”ืื—ืจื•ืŸ ื‘ืฉื•ืจื”. ืื—ืจื™ ืฉื—ืคืจื ื• ืืช ื”ื‘ืจื™ื›ื” ืžืžืœืื™ื ืื•ืชื” ื‘ืžื™ื ื•ื–ื” ื ืจืื” ื›ื›ื”:
 #######
 #######
 #######
 ..#####
 ..#####
 #######
 #####..
 #######
 .######
 .######
ื•ืขื›ืฉื™ื• ืฆืจื™ืš ืœื’ืœื•ืช ื›ืžื” ืžืฉื‘ืฆื•ืช ืขื ืกื•ืœืžื™ืช ื™ืฉ ื‘ืฆื™ื•ืจ. ื‘ื“ื•ื’ืžื” ื™ืฉ 64 (ืืชื ื™ื›ื•ืœื™ื ืœืกืคื•ืจ). ืื™ืš ืœื ืœืกืคื•ืจ ืกื•ืœืžื™ื•ืช ื›ืฉืจืื™ืชื™ ืืช ื”ืžื˜ืจื™ืฆื” ื”ื“ื‘ืจ ื”ืจืืฉื•ืŸ ืฉืจืฆื™ืชื™ ืœืขืฉื•ืช ื”ื™ื” ืœืฉืžื•ืจ ืื•ืชื” ื‘ืžืคื” ื‘ืกืงืืœื” ื›ืฉื”ืžืคืชื— ื”ื•ื ื”ืงื•ืื•ืจื“ื™ื ื˜ื•ืช ื•ื”ืขืจืš ื”ื•ื ืกื•ืœืžื™ืช ืื• ืžื—ืจื•ื–ืช ื”ืฆื™ื•ืจ ืื• true ืื• ืžื” ืฉืœื ื™ื”ื™ื”. ืื—ืจื™ ื–ื” ืจืฆื™ืชื™ ืœืงื—ืช ื ืงื•ื“ื” ื‘ืชื•ืš ื”ื‘ืจื™ื›ื” ื•ืœื”ืชื—ื™ืœ ืœื—ืคืฉ ืžืžื ื” ืืช ื›ืœ ื”ื ืงื•ื“ื•ืช ืฉืกื‘ื™ื‘ื” ื›ืœืคื™ ื—ื•ืฅ ืขื“ ืฉืื ื™ ืžื’ื™ืข ืœืงื• ื”ื‘ืจื™ื›ื” ื•ื›ืš ืื ื™ ื™ื›ื•ืœ ืœื“ืขืช ื›ืžื” ืžืฉื‘ืฆื•ืช ื ืžืฆืื•ืช ื‘ืชื•ืš ืฉื˜ื— ื”ื‘ืจื™ื›ื”. ืžื•ืกื™ืคื™ื ืืช ื–ื” ืœื”ื™ืงืฃ ื•ืžืฆืื ื• ืืช ืžืกืคืจ ื”ืกื•ืœืžื™ื•ืช. ืืคื™ืœื• ื›ืชื‘ืชื™ ืืช ื”ืงื•ื“. ืฉืชื™ ื”ืคื•ื ืงืฆื™ื•ืช ื”ืืœื” ื—ื•ืคืจื•ืช ืืช ื”ื‘ืจื™ื›ื”:
case class PaintingInstruction(dir: String, count: Long, color: String)

  def dig(input: Source): Canvas =
    val lineRE = """(\w) (\d+) \((#\w+)\)""".r

    input
      .getLines()
      .foldLeft(((0, 0), Map[(Int, Int), PaintingInstruction]())) { (acc, line) =>
        Try {
          val (pos, canvas) = acc
          val List(d, count, color) = lineRE.findFirstMatchIn(line).get.subgroups
          val paintingInstruction = PaintingInstruction(d, count.toInt, color)
          paint(pos, canvas, paintingInstruction)
        }.recover { err =>
          // skip line in case of error
          println(s"Error in line ${line} - ${err}")
          acc
        }.get
      }._2

  def paint(pos: Point, canvas: Canvas, cmd: PaintingInstruction): (Point, Canvas) =
    0L.until(cmd.count).foldLeft((pos, canvas)) { (acc, count) =>
      val ((row, column), canvas) = acc

      val nextCanvas = canvas.updated((row, column), cmd)
      cmd.dir match
        case "R" => ((row, column + 1), nextCanvas)
        case "L" => ((row, column - 1), nextCanvas)
        case "U" => ((row - 1, column), nextCanvas)
        case "D" => ((row + 1, column), nextCanvas)
    }

ื•ื”ืคื•ื ืงืฆื™ื” ื”ื–ืืช ืžื—ืคืฉืช ืืช ื›ืœ ื”ื ืงื•ื“ื•ืช ื‘ืชื•ืš ื”ื‘ืจื™ื›ื”:
@tailrec
def floodFill(canvas: Canvas, finished: Set[Point], inProgress: List[Point]): Set[Point] =
  inProgress match
    case head :: tail =>
      val (row, column) = head
      println(head)
      val neighbors = List(
        (row-1, column),
        (row+1, column),
        (row, column-1),
        (row, column+1),
      ).filterNot { p => canvas.contains(p) }
      .filterNot(finished.contains)
      .filterNot(inProgress.contains)

      floodFill(canvas, finished + head, tail ++ neighbors)

    case Nil => finished
ื”ืงื•ื“ ืคื•ืชืจ ืืช ื”ื—ืœืง ื”ืจืืฉื•ืŸ ืื‘ืœ ื ื›ืฉืœ ื‘ืฆื•ืจื” ื›ื•ืื‘ืช ื‘ื—ืœืง ื”ืฉื ื™ ื•ื”ื•ื ื’ื ืœื ื™ืขื™ืœ. ื ื™ืกื™ื•ืŸ ืฉื ื™ ื‘ื—ืœืง ื”ืฉื ื™ ืฉืœ ื”ืชืจื’ื™ืœ ืžืกืคืจื™ื ืœื ื• ืฉื‘ืขืฆื ืงืจืื ื• ืืช ื”ืฉื•ืจื” ืœื ื ื›ื•ืŸ ื›ืœ ื”ื–ืžืŸ. ื”ืžืกืคืจ ื”ืื—ืจื•ืŸ ื”ื•ื ื”ื“ื‘ืจ ื”ื—ืฉื•ื‘ - ื—ืžืฉ ื”ืกืคืจื•ืช ื”ืจืืฉื•ื ื•ืช ืฉืœื• ื”ืŸ ืžืกืคืจ ื‘ื‘ืกื™ืก 16, ื•ื”ืกื™ืคืจื” ื”ืื—ืจื•ื ื” ืžื™ื™ืฆื’ืช ืืช ื”ื›ื™ื•ื•ืŸ 0 ืขื‘ื•ืจ ื™ืžื™ื ื”, 1 ืขื‘ื•ืจ ืœืžื˜ื” 2 ืขื‘ื•ืจ ืฉืžืืœื” ื• 3 ืื•ืžืจ ืœืžืขืœื”. ื”ืžืกืคืจื™ื ื’ื“ื•ืœื™ื ื•ืœื›ืŸ ื›ื‘ืจ ืœื ืจื™ืืœื™ ืœืฉืžื•ืจ ืืช ื›ืœ ื”ืžืฉื‘ืฆื•ืช ื‘ืžื˜ืจื™ืฆื”. ืื ื”ื™ื™ื ื• ืฉื•ืžืจื™ื ื•ืžื—ืฉื‘ื™ื ืงืœื˜ ื”ื“ื•ื’ืžื” ื”ื™ื” ืžืกืชื›ื ื‘ 952408144115 ืžืฉื‘ืฆื•ืช.