Ecco cosa sto cercando di fare in generale. Per essere chiari, questo non è compito o per un concorso o altro. Speriamo, ho fatto la formulazione abbastanza chiaro:Esiste una soluzione LINQ elegante per SomeButNotAll()?
Problema
Dato un insieme di stringhe nello stesso formato, ma dove qualche fine in una lettera minuscola e alcuni non fai, riprendi in un insieme di uno di ogni stringa che non termina in una lettera minuscola, ma che ha almeno una stringa identica che termina in una lettera minuscola.
Esempio
Per farla semplice, diciamo che il formato stringa è \d+[a-z]?
, dove la parte comune è il numero. Dato {1, 4, 3a, 1b, 3, 6c}
, dovrei ricevere una permutazione di {1, 3}
perché 1 e 3 hanno entrambi un elemento con e senza una lettera minuscola alla fine.
soluzione alternativa
È possibile view this solution here.
Un modo ho pensato di fare questo è stato quello di dividere il set in elementi con e senza una lettera di suffisso minuscolo ({1, 4, 3}
e {3a, 1b, 6c}
), e poi tornare withoutSuffix.Where(x => withSuffix.Any(y => y.StartsWith(x)))
.
ho due problemi con questo:
non vedo un buon modo per dividere in due set, con il predicato
Regex.IsMatch(input, "[a-z]$")
. I due a cui pensavo erano due variabili definite allo stesso modo, ciascuna usando una clausolaWhere
e facendo la regex corrispondente a due volte per elemento, o trasformando il set per memorizzare i risultati della corrispondenza regolare e quindi formando le due variabili da quella.group...by
non sembra funzionare bene quando è necessario accedere a entrambi i set come questo, ma potrei sbagliarmi lì.Anche se la dimensione è abbastanza piccola per non preoccuparsi delle prestazioni, passare attraverso
withSuffix
una volta per elementowithoutSuffix
sembra poco elegante.
Soluzione Rilevante
È possibile view this solution here.
L'altro modo che mi è venuto in mente era prendere il prefisso comune e il suffisso opzionale: {1 => {"", b}, 3 => {a, ""}, 4 => {""}, 6 => {c}}
. Ciò è facilmente ottenibile catturando il prefisso e il suffisso con un'espressione regolare ((\d+)([a-z])?
) e raggruppando il suffisso con il prefisso in grouped
.
Da qui, sarebbe bello fare:
where grouped.SomeButNotAll(x => x == string.Empty)
select grouped.Key
O anche:
where grouped.ContainsSomeButNotAll(string.Empty)
select grouped.Key
mi potrebbe certamente creare uno di questi, ma purtroppo, il meglio che posso vedere in LINQ è :
where grouped.Contains(string.Empty) && grouped.Any(x => x != string.Empty)
select grouped.Key
Si sente super-ridondante. C'è già qualcosa di meglio in LINQ?
P.S. Sono aperto ad approcci migliori per risolvere il problema generale invece di renderlo un problema XY. L'eleganza è desiderata molto più che le prestazioni, ma (forse sono solo io) essere semplicemente dispendioso sembra ancora poco elegante.
Buona risposta. Potresti voler deduplicare il risultato alla fine però. – moarboilerplate
@moarboilerplate Non sono sicuro di cosa intendi. Gli insiemi hanno elementi unici. –
Questo mi fa quasi desiderare che ci fosse un 'PartitionSelect' di sorta. 'var partitions = input.PartitionSelect (s => char.IsLower (s.Last()), s => s.Substring (0, s.Length - 1), s => s);', con 'partizioni. TrueValues.Intersect (partitions.FalseValues); '(anche se non mi aspetterei set di hash da quello). – chris