Skip to content

fix camelCase #1072

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 25, 2025
Merged

fix camelCase #1072

merged 3 commits into from
Feb 25, 2025

Conversation

AndreiKingsley
Copy link
Collaborator

import io.kotest.matchers.shouldBe
import org.junit.Test

class ToCamelCase {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice tests!

Copy link
Collaborator

@zaleslaw zaleslaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! Thanks for fixing this and docs update

* This function renames all columns to `camelCase` by replacing all [delimiters][DELIMITERS_REGEX]
* and converting the first char to lowercase.
* Even [DataFrames][DataFrame] inside [FrameColumns][FrameColumn] are traversed recursively.
* This function renames all columns in this [DataFrame] to `camelCase` format.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*the camelCase format

* This function renames all columns in this [DataFrame] to `camelCase` format.
*
* All delimiters between words are removed, words are capitalized except for the first one.
* Places underscore between numbers.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you rewrite these two sentences? They don't flow well, and you jump from passive to active.

*
* All delimiters between words are removed, words are capitalized except for the first one.
* Places underscore between numbers.
* If the string does not contain any letters or numbers, it remains unchanged.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This no longer holds, does it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

letters or numbers

1.0.2 -> 1_0_2

._-. -> ._-.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh you're right

*
* @return trhe formatted string in lowerCamelCase.
*/
public fun String.toCamelCaseByDelimiters(delimiters: Regex = CAMEL_DEFAULT_DELIMITERS_REGEX): String =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this pollutes the public String scope. Maybe keep it internal for now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used in another module.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

damn :/

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can use friend modules

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it's fine for now. We will consider friend modules later probably, when we find out a safe way to use them.

private const val DELIMITERS = "[_\\s]"
public val DELIMITERS_REGEX: Regex = DELIMITERS.toRegex()
public val DELIMITED_STRING_REGEX: Regex = ".+$DELIMITERS.+".toRegex()
// Single regex to split words by non-alphanumeric characters, camelCase, and numbers

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newline

* "10-20-aa" -> "10_20Aa"
* ```
*
* @return trhe formatted string in lowerCamelCase.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

split(delimiters)
.filter { it.isNotBlank() }
.map { it.lowercase() }
.joinNumbers("_")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can make this an argument of the function, could be useful to change later if we need to :)

/**
* Joins consecutive numbers in a list with the given [separator].
*/
private fun List<String>.joinNumbers(separator: CharSequence): List<String> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm this seems a bit overcomplicated. It's not really clear what this function does and it's hard to check due to its complexity.
(What I think it does is [a1, 123, 345, bcd] -> [a1, 123_345, bcd], is that correct? This is then joined to "a1123_345Bcd". Actually, I think a1 and 123 should remain split as well.)

Wouldn't it be a lot simpler to perform a map-with-next and let joinWithCamelCaseString handle the joining part? Something like:

list.mapIndexed { i, current ->
    val next = list.getOrNull(i + 1) ?: return@mapIndexed current
    if (current.last().isDigit() && next.first().isDigit()) {
        current + "_"
    } else {
        current
    }
}

This would do [a1, 123, 345, bcd] -> [a1_, 123_, 345, bcd], after which they can be joined together like "a1_123_345Bcd"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It assumes that all numbers and strings are separated, I'll write a comment.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aah that was unclear indeed. Still, it might do with some simplification :)

Copy link
Collaborator Author

@AndreiKingsley AndreiKingsley Feb 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to separate numbers join logic

"singleword",
"word_with_underscores_and-dashes",
"10-20-aa",
"ROOM_1.11",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also add some special characters, like æ or letters from other alphabets?

@@ -18,7 +17,7 @@ internal fun String.withoutTopInterfaceName(topInterfaceName: ValidFieldName): S
this
}

internal fun String.snakeToLowerCamelCase(): String = toCamelCaseByDelimiters(DELIMITERS_REGEX)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just deprecate this function or remove it

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm hesitating because it's used in the implementation, I don't understand why and how it should work so I'm just afraid of breaking something

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright

@AndreiKingsley AndreiKingsley merged commit 0aaee79 into master Feb 25, 2025
6 checks passed
@AndreiKingsley AndreiKingsley deleted the camel_case_fix branch February 25, 2025 06:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

renameToCamelCase works is not as expected
3 participants