Opened 10 months ago

Last modified 9 months ago

#23943 closed enhancement

Mapcss "substring" function: allow negative end index to remove from the end — at Initial Version

Reported by: Famlam Owned by: team
Priority: normal Milestone: 24.11
Component: Core validator Version:
Keywords: mapcss substring Cc:

Description

The problem
Recently I had to use the following mapcss line:

fixAdd: concat("alt_name=", join_list(";", trim_list(split(";", replace(concat(";", join_list(";", trim_list(split(";", tag("alt_name")))), ";"), concat(";", tag("name"), ";"), ";")))));

This consists of three parts:

  1. the outer concat to just merge key and value (this is fine)
  2. the inner replace(...) which effectively removes the value of name from a ;-separated value of alt_name (this is fine)
  3. the in-between part join_list(";", trim_list(split(";", ...))) which effectively only serves to remove the ; at the start and end of the string.

Part 3 is obviously not elegant. Although there are other theoretical solutions, e.g.:

  • get(regexp_match("^;(.+);$", ...), 1)
  • substring(..., 1, length(...)-1)

where ... should be replaced by the part under number 2 (the replace(...)), they're obviously not the most elegant solutions either (especially the second which needs the lengthy replace(...)-part twice.

Proposed feature
A much nicer solution would be to permit negative end indices in the substring(str, start, end) function, which should mean to count the final index from the length of the string, e.g.: substring("foo bar baz", 1, -1) would return oo bar ba. This is especially useful for variable-length strings in mapcss.

I'm not familiar enough with Java to dare to make it a patch, but I can image the new function to look something like:

public static String substring(String s, float begin, float end) {
  return s == null ? null : s.substring((int) begin, (int) (end > 0 ? end : s.length() + end));
}

(Possibly with a safeguard that start <= (end > 0 ? end : s.length() + end), but this safeguard currently also doesn't exist for the positive-indices-only implementation)
Current code: here


On a side note, the current behavior is that JOSM crashes with java.lang.StringIndexOutOfBoundsException: Range [1, -1) out of bounds for length X when you use a negative end index (or when the start index is larger than the end index).


Revision:19207
Build-Date:2024-09-03 10:31:55

Change History (0)

Note: See TracTickets for help on using tickets.