diff --git a/string/methods.mbt b/string/methods.mbt index d508de6e4..a809ca63c 100644 --- a/string/methods.mbt +++ b/string/methods.mbt @@ -71,6 +71,7 @@ test "find" { ///| /// Returns the offset of the first character that satisfies the given predicate. /// If no such character is found, it returns None. +#locals(pred) pub fn View::find_by(self : View, pred : (Char) -> Bool) -> Int? { for i, c in self { if pred(c) { @@ -83,8 +84,14 @@ pub fn View::find_by(self : View, pred : (Char) -> Bool) -> Int? { ///| /// Returns the offset of the first character that satisfies the given predicate. /// If no such character is found, it returns None. +#locals(pred) pub fn String::find_by(self : String, pred : (Char) -> Bool) -> Int? { - self[:].find_by(pred) + for i, c in self { + if pred(c) { + return Some(i) + } + } + None } ///| @@ -101,6 +108,87 @@ test "find_by" { inspect!("πŸ˜€πŸ˜πŸ˜‚".find_by(fn(c) { c == 'πŸ˜‚' }), content="Some(2)") } +///| +/// Find the index of the first charcode that satisfies the given predicate. +/// If no such charcode is found, it returns None. +#locals(pred) +pub fn View::find_by_charcode(self : View, pred : (Int) -> Bool) -> Int? { + for i in 0.. Bool) -> Int? { + for i in 0..= '0' && c <= '9' }), + content="None", + ) + inspect!( + "hello123".find_by_charcode(fn(c) { c >= '0' && c <= '9' }), + content="Some(5)", + ) + + // Test case sensitivity + inspect!( + "hello".find_by_charcode(fn(c) { c >= 'A' && c <= 'Z' }), + content="None", + ) + inspect!( + "Hello".find_by_charcode(fn(c) { c >= 'A' && c <= 'Z' }), + content="Some(0)", + ) + + // Test non-ASCII characters + inspect!("Ξ±Ξ²Ξ³".find_by_charcode(fn(c) { c == 'Ξ²' }), content="Some(1)") + + // Test emoji and multi-byte characters + inspect!( + "πŸ˜€πŸ˜πŸ˜‚".find_by_charcode(fn(c) { c == 0xD83D }), + content="Some(0)", + ) // First code unit of πŸ˜€ + + // Test specific code point ranges + inspect!( + "Hello, δΈ–η•Œ!".find_by_charcode(fn(c) { c > 127 }), + content="Some(7)", + ) // First non-ASCII character + + // Test with complex predicate + inspect!("a1b2c3".find_by_charcode(fn(c) { c % 2 == 0 }), content="Some(2)") // '1' has code 49 which is odd +} + ///| /// Returns the offset of the last occurrence of the given substring. If the /// substring is not found, it returns None. diff --git a/string/string.mbti b/string/string.mbti index 03eca3a83..14a44474e 100644 --- a/string/string.mbti +++ b/string/string.mbti @@ -94,6 +94,7 @@ impl StringView { contains_char(Self, Char) -> Bool find(Self, Self) -> Int? find_by(Self, (Char) -> Bool) -> Int? + find_by_charcode(Self, (Int) -> Bool) -> Int? fold[A](Self, init~ : A, (A, Char) -> A) -> A from_array(Array[Char]) -> Self from_iter(Iter[Char]) -> Self @@ -148,6 +149,7 @@ impl String { ends_with(String, String) -> Bool find(String, StringView) -> Int? find_by(String, (Char) -> Bool) -> Int? + find_by_charcode(String, (Int) -> Bool) -> Int? fold[A](String, init~ : A, (A, Char) -> A) -> A from_array(Array[Char]) -> String from_iter(Iter[Char]) -> String