Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

210
Views
¿Hay operaciones perezosas any{}, all{} y none{} en Kotlin?

Estoy usando un estilo de programación funcional para resolver la pregunta fácil de Leetcode, Contar el número de cadenas consistentes . La premisa de esta pregunta es simple: cuente la cantidad de valores para los que se cumple el predicado de "todos los valores están en otro conjunto".

Pude hacer esto de manera bastante concisa así:

 class Solution { fun countConsistentStrings(allowed: String, words: Array<String>): Int { val permitted = allowed.toSet() return words.count{it.all{it in permitted}} } }

Sé que las secuencias de Java son perezosas, pero he leído que Kotlin solo es perezoso cuando se usa asSequence y, por lo demás, está ansioso.

Para las reducciones a un valor booleano basado en un predicado que usa any , none o all , tiene más sentido para mí que esto se haga de forma perezosa (por ejemplo, un solo false en all debería evaluar toda la expresión como false y dejar de evaluar el predicado para otros elementos).

¿Estas operaciones se implementan de esta manera o todavía se realizan con entusiasmo como otras operaciones en Kotlin? Si es así, ¿hay alguna manera de hacerlo perezosamente?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

No, esos métodos no son perezosos.

Primero, tenga en cuenta que hay varios métodos con cada uno de esos nombres: dos definidos en Sequence , dos definidos en cada uno de los trece tipos de matriz, dos en Map y uno en Iterable . Está claro que solo le interesan los definidos en Sequence , ya que esos otros tipos no admiten la pereza.

Entonces, ¡echemos un vistazo a los documentos! Los documentos para Sequence.any() , para Sequence.none() y para los métodos Sequence.all() dicen:

La operación es terminal .

Para confirmar lo que esto significa, los documentos del paquete kotlin.sequences dicen:

Si la operación de secuencia devuelve otra secuencia, que se produce de forma perezosa, se llama intermedia y, de lo contrario, la operación es terminal .

Así que esos métodos no son perezosos; cuando se ejecutan, hacen que la secuencia se evalúe en la medida necesaria para producir el valor requerido. (Sin embargo, no lo evalúan más allá de lo necesario, que puede ser lo que está preguntando. Después de todo, ¡ese es el punto de usar Sequences!)

(De hecho, puede ver por sus tipos que no hay forma de que sean perezosos: cada uno de ellos devuelve un valor Boolean , que es verdadero o falso. Para admitir la evaluación perezosa, tendrían que devolver un Future o un objeto similar con un getter que podría ser llamado para producir un resultado final, pero un Boolean ya es ese resultado final).

over 4 years ago · Santiago Trujillo Report

0

Creo que sobreinterpretas lo que significa perezosamente y con entusiasmo. Como "con entusiasmo" significa hacer siempre todo de la manera más ineficiente posible.

Las colecciones perezosas (Streams API, secuencias) intentan posponer el cálculo de sus contenidos hasta que sea necesario. Por otro lado, los cobros regulares realizan operaciones de inmediato cuando se solicitan. Pero eso no significa que si le preguntamos a una colección regular por su primer elemento, iterará sobre todos ellos sin motivo alguno.

De hecho, estas funciones se implementan casi exactamente de la misma manera tanto para iterables como para secuencias. La diferencia está en otras transformaciones y operadores. A continuación se muestra un ejemplo para any() :

 public inline fun <T> Iterable<T>.any(predicate: (T) -> Boolean): Boolean { if (this is Collection && isEmpty()) return false for (element in this) if (predicate(element)) return true return false } public inline fun <T> Sequence<T>.any(predicate: (T) -> Boolean): Boolean { for (element in this) if (predicate(element)) return true return false }
over 4 years ago · Santiago Trujillo Report

0

Los documentos no lo dicen explícitamente, pero esto es bastante fácil de probar.

 class A : Iterable<String>, Iterator<String> { public override fun iterator(): Iterator<String> { return this } public override fun hasNext(): Boolean { return true } public override fun next(): String { return "test" } } fun main(args: Array<String>) { val a = A() println(a.any { x -> x == "test" }) println(a.none { x -> x == "test" }) println(a.all { x -> x != "test" }) }

Aquí, A es una clase iterable tonta que simplemente produce "test" para siempre y nunca se agota. Luego usamos any , none y all para verificar si produce "test" o no. Es un iterable infinito, por lo que si alguna de estas tres funciones quisiera intentar agotarlo, el programa se colgaría para siempre. Pero puede ejecutarlo usted mismo y verá un true y dos false . El programa termina. Entonces, cada una de esas tres funciones se detuvo cuando encontró, respectivamente, una coincidencia, una no coincidencia y una no coincidencia.

¡Pruébelo en línea!

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!