# Staircase like function steps finding

I am making plots for data, and what I get are some staircase-like plots. Data I have is usually like this, for x and y axis (data given in lists is just an example):

x={0.405, 0.41, 0.415, 0.42, 0.425, 0.43, 0.435, 0.44, 0.445, 0.45,
0.455, 0.46, 0.465, 0.47, 0.475, 0.48, 0.485, 0.49, 0.495, 0.5}

y={0.105, 0.2, 0.2, 0.2, 0.301, 0.302, 0.305, 0.306, 0.307, 0.4,
0.4, 0.4, 0.465, 0.47, 0.475, 0.48, 0.485, 0.49, 0.495, 0.5}


How can I use Mathematica to get all intervals with repeating y values with corresponding interval of x values for which these repeats happens?

1. "For all pairs {xi, yi}, select those ones with the same y-value.":

g = GatherBy[Transpose[{x, y}], Last]

A typical entry of g looks like, eg

{{0.41, 0.2}, {0.415, 0.2}, {0.42, 0.2}}

(which is the second entry of g, or g[[2]], when using the example data)

2. "For every collection of pairs with the same y-coordinate, rearrange the pairs to obtain a list similar to {{x1, x2, ..., xn}, y0}":

(the first component of the new list contains the range of x-values and the second component is simply the common y-coordinate)

Define f = (Transpose[#] &) /* ({#[[1]], #[[-1, 1]]} &) which simply transposes its argument (a list of pairs) and then composes a list with first entry all the x's (#[[1]]) and second entry the first of the y's (#[[-1,1]]) which is the same as the rest of the y's (because, see question).

Below, using f along with g obtained above,

Apply[f[{##}]&, g, 1]

evaluates to

{ {{0.405}, 0.105}, {{0.41, 0.415, 0.42}, 0.2}, {{0.425}, 0.301}, {{0.43}, 0.302}, {{0.435}, 0.305}, {{0.44}, 0.306}, {{0.445}, 0.307}, {{0.45, 0.455, 0.46}, 0.4}, {{0.465}, 0.465}, {{0.47}, 0.47}, {{0.475}, 0.475}, {{0.48}, 0.48}, {{0.485}, 0.485}, {{0.49}, 0.49}, {{0.495}, 0.495}, {{0.5}, 0.5} }

when we use the data from the example in the question.

In short, defining the following function:

sol[x_, y_] := Module[{g, f},
g = GatherBy[Transpose[{x, y}], Last];
f = (Transpose[#] &) /* ({#[[1]], #[[-1, 1]]} &);
Apply[f[{##}] &, g, 1]
]


and evaluating it, using as inputs x and y (defined in the questiion) ie sol[x, y], should produce a list, where each entry is itself a list with the first component containing a range of x values and the second component containing the common y value corresponding to the range of x values.

KeyValueMap[{#2, #} &]@GroupBy[Transpose[{x, y}], Last -> First]


{{{0.405}, 0.105}, {{0.41, 0.415, 0.42}, 0.2}, {{0.425},   0.301}, {{0.43}, 0.302}, {{0.435}, 0.305}, {{0.44},   0.306}, {{0.445}, 0.307}, {{0.45, 0.455, 0.46}, 0.4}, {{0.465},   0.465}, {{0.47}, 0.47}, {{0.475}, 0.475}, {{0.48}, 0.48}, {{0.485},   0.485}, {{0.49}, 0.49}, {{0.495}, 0.495}, {{0.5}, 0.5}}