Skip to content

Commit 32a0c78

Browse files
committed
Add {insert,repsert}_by_ascending_key to collection/pairs.
1 parent bc5fd29 commit 32a0c78

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,10 @@
515515
- [`cardano/governance`](https://aiken-lang.github.io/stdlib/cardano/governance.html)
516516
- [`cardano/governance/protocol_parameters`](https://aiken-lang.github.io/stdlib/cardano/governance/protocol_parameters.html)
517517

518+
- New primitives in `aiken/collection/pairs`:
519+
- [`insert_by_ascending_key`](https://aiken-lang.github.io/stdlib/aiken/collection/pairs.html#insert_by_ascending_key)
520+
- [`repsert_by_ascending_key`](https://aiken-lang.github.io/stdlib/aiken/collection/pairs.html#repsert_by_ascending_key)
521+
518522
- New primitives in `aiken/crypto`:
519523
- [`blake2b_224`](https://aiken-lang.github.io/stdlib/aiken/crypto.html#blake2b_224)
520524
- [`keccak_256`](https://aiken-lang.github.io/stdlib/aiken/crypto.html#keccak_256)

lib/aiken/collection/pairs.ak

+112
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
//// > and thus allow for duplicate keys. This is reflected in the functions used
1313
//// > to interact with them.
1414

15+
use aiken/primitive/bytearray
16+
1517
// ## Inspecting
1618

1719
/// Get all values in the alist associated with a given key.
@@ -482,6 +484,61 @@ test delete_last_4() {
482484
delete_last(fixture, "a") == [Pair("a", 1), Pair("b", 2)]
483485
}
484486

487+
/// Insert a value in the `Pairs` at a given key. If the key already exists,
488+
/// the value is added in front.
489+
///
490+
/// ```aiken
491+
/// use aiken/primitive/bytearray
492+
///
493+
/// let result =
494+
/// []
495+
/// |> pairs.insert_by_ascending_key(key: "foo", value: 1, compare: bytearray.compare)
496+
/// |> pairs.insert_by_ascending_key(key: "bar", value: 2, compare: bytearray.compare)
497+
/// |> pairs.insert_by_ascending_key(key: "foo", value: 3, compare: bytearray.compare)
498+
///
499+
/// result == [Pair("bar", 2), Pair("foo", 3), Pair("foo", 1)]
500+
/// ```
501+
pub fn insert_by_ascending_key(
502+
self: Pairs<key, value>,
503+
key k: key,
504+
value v: value,
505+
compare: fn(key, key) -> Ordering,
506+
) -> Pairs<key, value> {
507+
when self is {
508+
[] ->
509+
[Pair(k, v)]
510+
[Pair(k2, v2), ..rest] ->
511+
if compare(k, k2) == Less {
512+
[Pair(k, v), ..self]
513+
} else {
514+
if k == k2 {
515+
[Pair(k, v), ..self]
516+
} else {
517+
[Pair(k2, v2), ..insert_by_ascending_key(rest, k, v, compare)]
518+
}
519+
}
520+
}
521+
}
522+
523+
test insert_by_ascending_key_1() {
524+
let m =
525+
[]
526+
|> insert_by_ascending_key("foo", 42, bytearray.compare)
527+
|> insert_by_ascending_key("foo", 14, bytearray.compare)
528+
529+
m == [Pair("foo", 14), Pair("foo", 42)]
530+
}
531+
532+
test insert_by_ascending_key_2() {
533+
let m =
534+
[]
535+
|> insert_by_ascending_key("foo", 42, bytearray.compare)
536+
|> insert_by_ascending_key("bar", 14, bytearray.compare)
537+
|> insert_by_ascending_key("baz", 1337, bytearray.compare)
538+
539+
m == [Pair("bar", 14), Pair("baz", 1337), Pair("foo", 42)]
540+
}
541+
485542
/// Apply a function to all key-value pairs in a alist, replacing the values.
486543
///
487544
/// ```aiken
@@ -515,6 +572,61 @@ test map_2() {
515572
map(fixture, with: fn(_, v) { v + 1 }) == [Pair("a", 2), Pair("b", 3)]
516573
}
517574

575+
/// Insert a value in the `Pairs` at a given key. If the key already exists,
576+
/// its value is replaced.
577+
///
578+
/// ```aiken
579+
/// use aiken/primitive/bytearray
580+
///
581+
/// let result =
582+
/// []
583+
/// |> pairs.repsert_by_ascending_key(key: "foo", value: 1, compare: bytearray.compare)
584+
/// |> pairs.repsert_by_ascending_key(key: "bar", value: 2, compare: bytearray.compare)
585+
/// |> pairs.repsert_by_ascending_key(key: "foo", value: 3, compare: bytearray.compare)
586+
///
587+
/// result == [Pair("bar", 2), Pair("foo", 3)]
588+
/// ```
589+
pub fn repsert_by_ascending_key(
590+
self: Pairs<key, value>,
591+
key k: key,
592+
value v: value,
593+
compare: fn(key, key) -> Ordering,
594+
) -> Pairs<key, value> {
595+
when self is {
596+
[] ->
597+
[Pair(k, v)]
598+
[Pair(k2, v2), ..rest] ->
599+
if compare(k, k2) == Less {
600+
[Pair(k, v), ..self]
601+
} else {
602+
if k == k2 {
603+
[Pair(k, v), ..rest]
604+
} else {
605+
[Pair(k2, v2), ..repsert_by_ascending_key(rest, k, v, compare)]
606+
}
607+
}
608+
}
609+
}
610+
611+
test repsert_by_ascending_key_1() {
612+
let m =
613+
[]
614+
|> repsert_by_ascending_key("foo", 42, bytearray.compare)
615+
|> repsert_by_ascending_key("foo", 14, bytearray.compare)
616+
617+
m == [Pair("foo", 14)]
618+
}
619+
620+
test repsert_by_ascending_key_2() {
621+
let m =
622+
[]
623+
|> repsert_by_ascending_key("foo", 42, bytearray.compare)
624+
|> repsert_by_ascending_key("bar", 14, bytearray.compare)
625+
|> repsert_by_ascending_key("baz", 1337, bytearray.compare)
626+
627+
m == [Pair("bar", 14), Pair("baz", 1337), Pair("foo", 42)]
628+
}
629+
518630
// ## Transforming
519631

520632
/// Fold over the key-value pairs in a pairs. The fold direction follows keys

0 commit comments

Comments
 (0)