Supongamos que tengo una matriz como esta:
arr=[["1"], ["1"], ["2", "2"], ["2.1", "0.8"], ["2.2", "0.2"], ["1"], ["2", "3"], ["2", "0.8"], ["2", "0.4"], ["1"], ["2"], ["1", "0.8"], ["2", "0.4"], ["3", "0.3"]]es decir, una serie de sublistas (1 o más) de longitud 1 seguida de una serie de sublistas (1 o más) de longitud superior a 1.
Quiero dividir esa lista en:
[[["1"], ["1"], ["2", "2"], ["2.1", "0.8"], ["2.2", "0.2"]], [["1"], ["2", "3"], ["2", "0.8"], ["2", "0.4"]], [["1"], ["2"], ["1", "0.8"], ["2", "0.4"], ["3", "0.3"]]]es decir, las sublistas de longitud 1 combinadas con las siguientes sublistas de longitud superior a 1 en una sola sublista de esas sublistas.
Esto funciona:
data = [] while arr.length > 0 tmp = [] while arr.length > 0 && arr[0].length() == 1 tmp << arr.shift end while arr.length > 0 && arr[0].length() > 1 tmp << arr.shift end data << tmp end p data # [[["1"], ["1"], ["2", "2"], ["2.1", "0.8"], ["2.2", "0.2"]], [["1"], ["2", "3"], ["2", "0.8"], ["2", "0.4"]], [["1"], ["2"], ["1", "0.8"], ["2", "0.4"], ["3", "0.3"]]] Pero eso parece súper torpe. ¿Hay un .groupby o flip/flop o alguna forma de enumerador de Ruby que me falta para hacer esto más fácilmente?
Como una mejora en la respuesta de @dawg, si el bloque que pasamos a :slice_when verifica que la longitud de b sea mayor que la longitud de a :
data = arr.slice_when { |a, b| b.length < a.length }.to_aEl resultado es:
[[["1"], ["1"], ["2", "2"], ["2.1", "0.8"], ["2.2", "0.2"]], [["1"], ["2", "3"], ["2", "0.8"], ["2", "0.4"]], [["1"], ["2"], ["1", "0.8"], ["2", "0.4"], ["3", "0.3"]]] Esto solo maneja correctamente situaciones en las que las matrices tienen una longitud 1 o 2 . Para hacer esto más robusto, podemos verificar que solo estamos haciendo esto cuando b tiene una longitud 1 .
data = arr.slice_when { |a, b| b.length == 1 && b.length < a.length }.to_aAhora si:
arr = [["1"], ["1"], ["2", "2"], ["2.1", "0.8"], ["2.2", "0.2"], ["1", "3", "4"], ["1", "1"], ["1"], ["2", "3"], ["2", "0.8"], ["2", "0.4"], ["1"], ["2"], ["1", "0.8"], ["2", "0.4"], ["3", "0.3"]]El resultado es:
[[["1"], ["1"], ["2", "2"], ["2.1", "0.8"], ["2.2", "0.2"], ["1", "3", "4"], ["1", "1"]], [["1"], ["2", "3"], ["2", "0.8"], ["2", "0.4"]], [["1"], ["2"], ["1", "0.8"], ["2", "0.4"], ["3", "0.3"]]]