¿Cuáles son algunos enfoques inteligentes (breves e idiomáticos) para tomar una lista de cadenas y devolver una sola cadena correctamente puntuada construida a partir de la lista, con cada elemento citado.
Esto se me ocurrió al experimentar con Groovy , para lo cual mi solución demasiado literal pero ilustrativa es
def temp = things.collect({"\'${it}\'"})
switch (things.size()) {
case 1:
result = temp[0]
break
case 2:
result = temp.join(" and ")
break
default:
result = temp.take(temp.size()-1).join(", ") + ", and " + temp[-1]
break
}
Es decir, ['1']debería ceder '1', ['1','2']debería ceder '1 and 2', [¿ves lo que hice allí?] Y ['1','2','3']debería ceder '1, 2, and 3'.
Tengo algunas buenas respuestas para Groovy, pero me gustaría ver qué pueden hacer otros idiomas.
¿Cuáles son algunos enfoques inteligentes y compactos en varios idiomas que aprovechan las características y modismos de esos idiomas?

['we invited the stripper','JFK','Stalin']Respuestas:
CSS,
132116115 bytesMostrar fragmento de código
CSS no se ve con demasiada frecuencia en el código de golf porque solo puede formatear texto, pero en realidad funciona para este desafío y pensé que sería divertido hacerlo. Véalo en acción usando el fragmento de arriba (haga clic en "Mostrar fragmento de código").
La lista debe estar en un archivo HTML vinculado con cada elemento rodeado de
<a>etiquetas y separados por saltos de línea. Los elementos de la lista deben ser los únicos elementos en su elemento principal, por ejemploExplicación
Consideremos la versión anterior sin golf. Si no está familiarizado con el funcionamiento de CSS, todo lo que esté fuera de las llaves es un selector que determina el conjunto de elementos HTML a los que se aplican las declaraciones dentro de las llaves. Cada par selector-declaración se llama regla . (Es más complicado que eso, pero será suficiente para esta explicación). Antes de aplicar cualquier estilo, la lista aparece separada solo por espacios.
Queremos agregar comas después de cada palabra, excepto la última, excepto las listas de dos palabras, que no tienen comas. El primer selector,
a:not(:last-child):nth-child(n+2):afterselecciona todos los elementos excepto el primero y el último.:nth-child(n+2)es una forma más corta de decir:not(:first-child), y básicamente funciona seleccionando elementos cuyo índice (comenzando en 1) es mayor o igual a 2. (Sí, todavía me confunde un poco. Los documentos MDN podrían ayudar).Ahora solo tenemos que seleccionar el primer elemento para obtener una coma si hay tres o más elementos en total.
a:nth-last-child(n+3):afterfunciona como:nth-child, pero contando desde atrás, por lo que selecciona todos los elementos excepto los dos últimos. La coma toma la unión de los dos conjuntos, y usamos el:afterpseudo-elemento para agregarcontentinmediatamente después de cada elemento seleccionado.La segunda regla es más fácil. Necesitamos agregar "y" antes del último elemento en la lista, a menos que sea un solo elemento. En otras palabras, necesitamos seleccionar el último elemento precedido por otro elemento.
+es el selector de hermanos adyacentes en CSS.fuente
<li>.<li>sería ideal, pero eso agregaría dos caracteres adicionales a los selectores. Elegí<a>porque es una letra y no aplica su propio formato.Haskell:
81, 7774 caracteresCaracterísticas de Haskell: coincidencia de patrones
fuente
f[x,y,z]f["a","b","c"]se supone que es,"a, b, and c"pero lo es"a,b and c"y++", and "++zporf[y++",",z]:)Ruby, 47 bytes
Explicación
$*).$*tiene un tercer elemento ($*[2]no devuelve nada), tome todos los elementos menos el último y conviértalos en una cadena separada por comasArray#*. Finalmente agregue una coma extra, la cadena" and "y el último argumento de línea de comando.$*no tiene un tercer elemento, se dieron dos, uno o cero argumentos. Los argumentos se pueden unir de forma segura con la cadena" and "y producir el resultado correcto.fuente
Pitón 2 (61)
El truco principal es cortar parte de la unión final
", and "para uno y dos elementos. Para uno, todo se corta, y para dos, se elimina la coma. Esto se hace cortando[8-7*len(s):](notando queses uno más corto después depop).Desafortunadamente,
dno puede ser reemplazado simplemente con su expresión opopsucedería demasiado tarde.fuente
scons=input()y eliminar la primera línea, si no me equivoco. Ahorra 2 caracteres.svarias veces.CSS,
62 caracteres112 caracteresInspirado por las otras entradas, incluso más cortas. Tenga en cuenta que requiere que los elementos A no estén separados por espacios en blanco:
http://jsfiddle.net/olvlvl/1Ls79ocb/
Arreglo para el "uno y dos", como lo señaló Dennis:
http://jsfiddle.net/olvlvl/1Ls79ocb/3/
fuente
Perl (v 5.10+) -
37353428para ejecutarse
perl -ape, con la lista de espacio provisto separado enSTDIN.Salida para varias entradas:
fuente
s/(\S+)$/and $1/$ancla en su edición, por lo que sefoo bar bazconvierte en una entrada defoo, and bar, baz. Además, puede eliminar uno de los espacios haciendos/( \S+)$/ and$1/$#F>1como@F>2para cortar una más. Lo siento por todas las sugerencias para micro mejoras, realmente me gusta esta respuesta :)echo -n ... | wc -c). Si pierdes el espacio antes(\S+)llegarías a 33 caracteres, pero si lo ingresastest thisobtendrástest and this(dos espacios despuéstest), así que sin más Creo que eso está mal.Javascript (63)
l=a.length;l>2&&(a[l-1]='and '+a[l-1]);a.join(l>2?', ':' and ')Casos:
a = [1]=>1a = [1, 2]=>1 and 2a = [1, 2, 3]=>1, 2, and 3Advertencia: esto modificará el último elemento en una matriz con longitud> 2.
fuente
&&GNU sed - 69 caracteres incluyendo 1 para
-rbanderaToma una lista separada por espacios (bastante idiomática para los scripts de shell).
Ejemplo
fuente
1 and 2lugar de1, 2Python 2 -
71, 7068Recuento de caracteres incluyendo ambos
inputyprint.fuente
Ruby, 57 bytes
Estoy uniendo la cadena con
,y luego estoy reemplazando la última coma en la cadena con unaand(y una coma opcional dependiendo de la longitud de la lista).fuente
Cobra - 60
La
List<of T>.joinfunción de Cobra le permite especificar un separador diferente para los dos elementos finales de la lista, que es lo que lo hace tan corto.fuente
Perl - 59
Une la lista con comas, luego, si la lista tiene más de un elemento, agrega
' and'después de la última coma (si longitud> = 3) o reemplaza la última coma con ella (si longitud == 2).fuente
PHP,
192167146136 caracteres:Basado en una función que escribí hace años en http://www.christopherbloom.com/2011/05/21/join-implode-an-array-of-string-values-with-formatting/
fuente
Lote: 151 bytes
Nota; debe llamar al script desde
cmdel/vconjunto de interruptores comoon, esto es para que no tenga que incluir el extensosetLocal enableDelayedExpansionen el script. De lo contrario, agregue 30 al recuento de bytes y llame al script normalmente.fuente
Groovy,
47 4357 caracteres, JavaScript ES6 56 caracteresMaravilloso:
Como la matriz está llena de caracteres, podemos reemplazarlos
a.size>1pora[1]JavaScript, ES6:
Ambos casos suponen que la variable a tiene la matriz en cuestión.
fuente
PHP,
8684 caracteresCon la matriz inicializada, comenzamos a contar:
Prettified:
El último elemento de la lista se modifica. Esto debería estar bien porque en PHP, la asignación de matriz y las llamadas a funciones realizan copias.
fuente
CJam,
35302827 bytesEste es un programa que lee desde STDIN e imprime en STDOUT. Pruébalo en línea.
Cómo funciona
Ejecución de ejemplo
fuente
Hojas de cálculo de Google,
67686792 bytesLa entrada comienza en la celda
A1y continúa hacia abajo sin importar cuántas entradas existan.JOINlos fusiona a todos en una cadena con un espacio de coma entre cada uno.FILTERelimina cualquier espacio en blanco para que no termines con comas infinitas al final.SUBSTITUTEreemplaza la última coma (que se encuentraCOUNTAcontando las entradas que no están en blanco).No es muy emocionante, pero es factible en una sola celda.
fuente
)de esta fórmula para -1 Byte; Bueno dang, esa fue la edición más rápida que he visto +1A:A>""deben convertirse aA:A<>""y esto no implementa omitir la coma de Oxford en casos de solo 2 objetos>"". La corrección rápida que hice antes claramente no fue probada. No me gusta la dirección que fue ...JavaScript (ES6) 60
Suponiendo que no hay cadenas vacías en la matriz de entrada
Prueba en la consola FireFox / Firebug
Salida
fuente
node --harmonycon una serie de cadenasvar a = 'abcdefgh'.split('');, pero simplemente se queda allí con una...y parece no hacer nada. También +1 por usar la característica exclusiva de ES6()=>.f=(a,b=a.pop())=>a[0]?a.join(', ')+', and '+b:btambién es correcto y 13 bytes más corto.JavaScript -
6056716763No es exactamente un enfoque idiomático, pero me divertí escribiéndolo y me gusta la expresión regular.
Suponiendo que la matriz se almacena en
var a:Acortado simplemente comprobando el índice
[2]: (yay boolean coercion)Aparentemente apestaba en las pruebas y salté una prueba de entrada única. Aquí está la versión fija:
Afeité 2 caracteres invirtiendo mis booleanos y 3 más moviendo el espacio desde la concatenación al entonces / más del primer ternario:
Gracias a @tomsmeding por recordarme que no tengo que forzar a mis booleanos porque JS lo hace por mí. También me di cuenta de que olvidé eliminar los paréntesis que separan el primer ternario de la concatenación dentro de
join():¿Lo hice bien? Obligatorio nuevo golfista disculpa.
fuente
!!nada;a[2]?A:BYa funciona. Puede que tengas que invertir tus booleanos nuevamente .a[i]equivale a verdadero . Bueno, casi. Supongo que si obtiene 2 entradas, su matriz tiene una longitud dos. Luegoa[2]===undefinedyundefinedevalúa afalse. EDIT: tu edición es lo que quería decir :)Golfscript -
31393430¡Hola Mundo! Soy un acechador de mucho tiempo, primer cartel. Aquí está mi solución de 30 bytes en Golfscript (dada la matriz como [1 2 3] ya está en la pila).
Los resultados son adecuados para todos los casos de prueba.
EDITAR: ¡Toma eso, CJam!
fuente
Xojo,
527183 caracteresTenga en cuenta que UBound es uno menos que la longitud de la matriz.
fuente
Excel VBA, 108 bytes
Función de ventana inmediata anónima de VBE que toma la entrada como matriz delimitada por espacios desde el rango
A1y las salidas a la ventana inmediata de VBE.fuente
Raqueta 87
fuente
Python 62 caracteres
Suponiendo que yo sea la lista de cadenas:
fuente
C # 102 Chars
fuente
Julia (53)
Toma argumentos de STDIN y sale a STDOUT
Solución usando Base.join (items, delim [, last])
Editar:
Casos de prueba
1
1 y 2
1, 2 y 3
fuente
1, 2, and 3, no1, 2 and 3.Rant (108)
Sin golf:
Uso:
Pruébalo en línea
fuente
Pyth, 28
Ejemplos:
fuente
TypeError: can only concatenate list (not "str") to list). Funciona bien con la última versión.PHP - 72
Configurar la entrada:
Y luego el proceso:
fuente