├── .gitignore ├── README.md ├── linq-log.txt └── src ├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── servicestack │ │ └── net │ │ └── kotlinlinqexamples │ │ └── ApplicationTest.kt │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── servicestack │ │ └── net │ │ └── kotlinlinqexamples │ │ ├── AggregateOperators.kt │ │ ├── Conversion.kt │ │ ├── ElementOperators.kt │ │ ├── GenerationOperators.kt │ │ ├── Grouping.kt │ │ ├── JoinOperators.kt │ │ ├── MainActivity.kt │ │ ├── MiscOperators.kt │ │ ├── Ordering.kt │ │ ├── Partitioning.kt │ │ ├── Projections.kt │ │ ├── Quantifiers.kt │ │ ├── QueryExecution.kt │ │ ├── Restrictions.kt │ │ ├── SetOperators.kt │ │ ├── extensions.kt │ │ └── support │ │ ├── Customer.kt │ │ ├── Data.kt │ │ ├── Order.kt │ │ └── Product.kt │ └── res │ ├── drawable-hdpi │ └── ic_action_android.png │ ├── drawable-mdpi │ └── ic_action_android.png │ ├── drawable-xhdpi │ └── ic_action_android.png │ ├── drawable-xxhdpi │ └── ic_action_android.png │ ├── layout │ └── activity_main.xml │ ├── menu │ └── menu_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── raw │ └── customers.json │ ├── values-v21 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src.iml /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | 15 | # Gradle files 16 | .gradle/ 17 | build/ 18 | /*/build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 101 C# LINQ Samples in Kotlin 2 | ============================= 3 | 4 | This project contains the [C# 101 LINQ Samples](http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b) 5 | rewritten to Kotlin. Like the existing [Java LINQ Examples](https://github.com/mythz/java-linq-examples), 6 | Kotlin examples run and have their results displayed inside an Android App courtesy of the 7 | [rich support for Kotlin in Android Studio](https://kotlinlang.org/docs/tutorials/kotlin-android.html). 8 | 9 | Compare Kotlin to other LINQ examples written in: 10 | 11 | - [Java](https://github.com/mythz/java-linq-examples) 12 | - [Groovy](https://gitlab.com/svermeulen/groovy-linq-samples) 13 | - [Swift](https://github.com/mythz/swift-linq-examples) 14 | - [Clojure](https://github.com/mythz/clojure-linq-examples) 15 | - [Dart](https://github.com/mythz/dart-linq-examples) 16 | - [Elixir](https://github.com/omnibs/elixir-linq-examples) 17 | - [Python](https://github.com/rogerwcpt/python-linq-samples) 18 | - [#Script code](https://sharpscript.net/linq/restriction-operators?lang=code) 19 | - [#Script lisp](https://sharpscript.net/linq/restriction-operators?lang=lisp) 20 | 21 | Comparing against [Java examples](https://github.com/mythz/java-linq-examples) 22 | showcases the power and expressiveness of both languages ability for developing native Android Apps 23 | where Java 7 is by far the worst language for functional/LINQ-style programming vs Kotlin which is one of 24 | the best - resulting in a much more readable and maintainable code-base that's less than 1/2 the size. 25 | 26 | ## Kotlin Android Resources 27 | 28 | To help getting started with Kotlin, we'll maintain links to useful resources helping to develop Android Apps 29 | with Kotlin below: 30 | 31 | - [Getting started with Android and Kotlin](https://kotlinlang.org/docs/tutorials/kotlin-android.html) _(kotlinlang.org)_ 32 | - [Kotlin for Android Developers](http://www.javaadvent.com/2015/12/kotlin-android.html) _(javaadvent.com)_ 33 | - [Android Development with Kotlin - Jake Wharton](https://www.youtube.com/watch?v=A2LukgT2mKc&feature=youtu.be) _(youtube.com)_ 34 | 35 | ### [Call .NET Web Services from Kotlin](http://docs.servicestack.net/kotlin-add-servicestack-reference) 36 | 37 | If you're looking to create an effortles typed API for consuming .NET Web Services in JVM or Kotlin Android Apps checkout ServiceStack's 38 | [Kotlin Add ServiceStack Reference](http://docs.servicestack.net/kotlin-add-servicestack-reference). 39 | 40 | ## Running the examples 41 | 42 | Each of the LINQ Examples can be run from the included Android App with its results logged to the screen: 43 | 44 | ![](https://raw.githubusercontent.com/ServiceStack/Assets/master/img/wikis/kotlin/kotlin-linq-examples.png) 45 | 46 | Run the included [Android Studio project](https://github.com/mythz/kotlin-linq-examples/tree/master/src) to execute all the examples. You can also choose to only run specific examples by commenting out any of the sections you're not interested in [MainActivity.kt](https://github.com/mythz/kotlin-linq-examples/blob/c5cd7a28ffd4efd5d715c6107d9a6076fbb27227/src/app/src/main/java/servicestack/net/kotlinlinqexamples/MainActivity.kt#L41-L54). 47 | 48 | A copy of the LINQ examples output is also available in [linq-log.txt](https://raw.githubusercontent.com/mythz/kotlin-linq-examples/master/linq-log.txt). 49 | 50 | ### Contents 51 | 52 | The samples below mirrors the C# LINQ samples layout with the names of the top-level Java methods matching their corresponding C# examples. 53 | 54 | #### [LINQ - Restriction Operators](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/Restrictions.kt) / [MSDN C#](http://code.msdn.microsoft.com/LINQ-Restriction-Operators-b15d29ca) 55 | #### [LINQ - Projection Operators](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/Projections.kt) / [MSDN C#](http://code.msdn.microsoft.com/LINQ-to-DataSets-09787825) 56 | #### [LINQ - Partitioning Operators](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/Partitioning.kt) / [MSDN C#](http://code.msdn.microsoft.com/LINQ-Partitioning-Operators-c68aaccc) 57 | #### [LINQ - Ordering Operators](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/Ordering.kt) / [MSDN C#](http://code.msdn.microsoft.com/SQL-Ordering-Operators-050af19e) 58 | #### [LINQ - Grouping Operators](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/Grouping.kt) / [MSDN C#](http://code.msdn.microsoft.com/LINQ-to-DataSets-Grouping-c62703ea) 59 | #### [LINQ - Set Operators](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/SetOperators.kt) / [MSDN C#](http://code.msdn.microsoft.com/LINQ-Set-Operators-374f34fe) 60 | #### [LINQ - Conversion Operators](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/Conversion.kt) / [MSDN C#](http://code.msdn.microsoft.com/LINQ-Conversion-Operators-e4e59714) 61 | #### [LINQ - Element Operators](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/ElementOperators.kt) / [MSDN C#](http://code.msdn.microsoft.com/LINQ-Element-Operators-0f3f12ce) 62 | #### [LINQ - Generation Operators](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/GenerationOperators.kt) / [MSDN C#](http://code.msdn.microsoft.com/LINQ-Generation-Operators-8a3fbff7) 63 | #### [LINQ - Quantifiers](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/Quantifiers.kt) / [MSDN C#](http://code.msdn.microsoft.com/LINQ-Quantifiers-f00e7e3e) 64 | #### [LINQ - Aggregate Operators](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/AggregateOperators.kt) / [MSDN C#](http://code.msdn.microsoft.com/LINQ-Aggregate-Operators-c51b3869) 65 | #### [LINQ - Miscellaneous Operators](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/MiscOperators.kt) / [MSDN C#](http://code.msdn.microsoft.com/LINQ-Miscellaneous-6b72bb2a) 66 | #### [LINQ - Query Execution](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/QueryExecution.kt) / [MSDN C#](http://code.msdn.microsoft.com/LINQ-Query-Execution-ce0d3b95) 67 | #### [LINQ - Join Operators](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/JoinOperators.kt) / [MSDN C#](http://code.msdn.microsoft.com/LINQ-Join-Operators-dabef4e9) 68 | 69 | ## Kotlin Functional Utils 70 | 71 | Kotlin has great language and built-in library support to simplify programming in a functional-style where most of the LINQ examples 72 | are able to use Kotlins built-in utils. Some of the more advanced LINQ examples like JOIN's were missing in Kotlins standard library, for this 73 | we leverage the existing implementations in 74 | [ServiceStack's Java and Android Client Library](http://docs.servicestack.net/java-add-servicestack-reference): **net.servicestack:android**. 75 | 76 | ### Install 77 | 78 | To include it in your Android Studio project, add it to your **build.gradle** dependency, e.g: 79 | 80 | dependencies { 81 | compile fileTree(dir: 'libs', include: ['*.jar']) 82 | compile 'net.servicestack:android:1.0.31' 83 | } 84 | 85 | Pure Java projects should add the **net.servicestack:client** dependency instead: 86 | 87 | dependencies { 88 | compile 'net.servicestack:client:1.0.31' 89 | } 90 | 91 | Alternatively this library is also automatically added when Adding a Typed Remote Service Reference with ServiceStack IDE Plugins for 92 | [Intellij IDEA](http://docs.servicestack.net/java-add-servicestack-reference) and 93 | [Eclipse Maven projects](https://github.com/ServiceStack/ServiceStack.Java/tree/master/src/ServiceStackEclipse#eclipse-integration-with-servicestack). 94 | 95 | ## [Kotlin Extensions](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/extensions.kt) 96 | 97 | Only a [2 extensions](https://github.com/mythz/kotlin-linq-examples/blob/master/src/app/src/main/java/servicestack/net/kotlinlinqexamples/extensions.kt) 98 | were required to cover Kotlin's missing `difference` API. 99 | 100 | ## Side-by-side - C# LINQ vs Kotlin 101 | 102 | For a side-by-side comparison, the original **C#** source code is displayed above the equivalent **Kotlin** translation. 103 | 104 | - The **Output** shows the logging output of running the **Kotlin** Android App. 105 | - Outputs ending with `...` illustrates only a partial response is displayed. 106 | - The C# ObjectDumper util used is downloadable from MSDN - [ObjectDumper.zip](http://code.msdn.microsoft.com/Visual-Studio-2008-C-d295cdba/file/46086/1/ObjectDumper.zip) 107 | 108 | 109 | LINQ - Restriction Operators 110 | ---------------------------- 111 | 112 | ### linq1: Where - Simple 1 113 | 114 | ```csharp 115 | //c# 116 | public void Linq1() 117 | { 118 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 119 | 120 | var lowNums = 121 | from n in numbers 122 | where n < 5 123 | select n; 124 | 125 | Console.WriteLine("Numbers < 5:"); 126 | foreach (var x in lowNums) 127 | { 128 | Console.WriteLine(x); 129 | } 130 | } 131 | ``` 132 | ```kotlin 133 | //kotlin 134 | fun linq1() { 135 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 136 | 137 | val lowNums = numbers.filter { it < 5 } 138 | 139 | Log.d("Numbers < 5:") 140 | lowNums.forEach { Log.d(it) } 141 | } 142 | ``` 143 | #### Output 144 | 145 | Numbers < 5: 146 | 4 147 | 1 148 | 3 149 | 2 150 | 0 151 | 152 | ### linq2: Where - Simple 2 153 | ```csharp 154 | //c# 155 | public void Linq2() 156 | { 157 | List products = GetProductList(); 158 | 159 | var soldOutProducts = 160 | from p in products 161 | where p.UnitsInStock == 0 162 | select p; 163 | 164 | Console.WriteLine("Sold out products:"); 165 | foreach (var product in soldOutProducts) 166 | { 167 | Console.WriteLine("{0} is sold out!", product.ProductName); 168 | } 169 | } 170 | ``` 171 | ```kotlin 172 | //kotlin 173 | fun linq2() { 174 | val soldOutProducts = products.filter { it.unitsInStock == 0 } 175 | 176 | Log.d("Sold out products:") 177 | soldOutProducts.forEach { Log.d("${it.productName} is sold out!") } 178 | } 179 | ``` 180 | #### Output 181 | 182 | Sold out products: 183 | Chef Anton's Gumbo Mix is sold out! 184 | Alice Mutton is sold out! 185 | Thüringer Rostbratwurst is sold out! 186 | Gorgonzola Telino is sold out! 187 | Perth Pasties is sold out! 188 | 189 | ### linq3: Where - Simple 3 190 | ```csharp 191 | //c# 192 | public void Linq3() 193 | { 194 | List products = GetProductList(); 195 | 196 | var expensiveInStockProducts = 197 | from p in products 198 | where p.UnitsInStock > 0 && p.UnitPrice > 3.00M 199 | select p; 200 | 201 | Console.WriteLine("In-stock products that cost more than 3.00:"); 202 | foreach (var product in expensiveInStockProducts) 203 | { 204 | Console.WriteLine("{0} is in stock and costs more than 3.00.", product.ProductName); 205 | } 206 | } 207 | ``` 208 | ```kotlin 209 | //kotlin 210 | fun linq3() { 211 | val expensiveInStockProducts = products.filter { it.unitsInStock > 0 && it.unitPrice > 3.00 } 212 | 213 | Log.d("In-stock products that cost more than 3.00:") 214 | expensiveInStockProducts.forEach { Log.d("${it.productName} is in stock and costs more than 3.00.") } 215 | } 216 | ``` 217 | #### Output 218 | 219 | In-stock products that cost more than 3.00: 220 | Chai is in stock and costs more than 3.00. 221 | Chang is in stock and costs more than 3.00. 222 | Aniseed Syrup is in stock and costs more than 3.00. 223 | ... 224 | 225 | ### linq4: Where - Drilldown 226 | ```csharp 227 | //c# 228 | public void Linq4() 229 | { 230 | List customers = GetCustomerList(); 231 | 232 | var waCustomers = 233 | from c in customers 234 | where c.Region == "WA" 235 | select c; 236 | 237 | Console.WriteLine("Customers from Washington and their orders:"); 238 | foreach (var customer in waCustomers) 239 | { 240 | Console.WriteLine("Customer {0}: {1}", customer.CustomerID, customer.CompanyName); 241 | foreach (var order in customer.Orders) 242 | { 243 | Console.WriteLine(" Order {0}: {1}", order.OrderID, order.OrderDate); 244 | } 245 | } 246 | } 247 | ``` 248 | ```kotlin 249 | //kotlin 250 | fun linq4() { 251 | val waCustomers = customers.filter { "WA" == it.region } 252 | 253 | Log.d("Customers from Washington and their orders:") 254 | waCustomers.forEach { c -> 255 | Log.d("Customer ${c.customerId} ${c.companyName}") 256 | c.orders.forEach { Log.d(" Order ${it.orderId}: ${dateFmt(it.orderDate)}") } 257 | } 258 | } 259 | ``` 260 | #### Output 261 | 262 | Customers from Washington and their orders: 263 | Customer LAZYK Lazy K Kountry Store 264 | Order 10482: 1997/03/21 265 | Order 10545: 1997/05/22 266 | Customer TRAIH Trail's Head Gourmet Provisioners 267 | Order 10574: 1997/06/19 268 | Order 10577: 1997/06/23 269 | Order 10822: 1998/01/08 270 | ... 271 | 272 | ### linq5: Where - Indexed 273 | ```csharp 274 | //c# 275 | public void Linq5() 276 | { 277 | string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; 278 | 279 | var shortDigits = digits.Where((digit, index) => digit.Length < index); 280 | 281 | Console.WriteLine("Short digits:"); 282 | foreach (var d in shortDigits) 283 | { 284 | Console.WriteLine("The word {0} is shorter than its value.", d); 285 | } 286 | } 287 | ``` 288 | ```kotlin 289 | //kotlin 290 | fun linq5() { 291 | val digits = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") 292 | 293 | val shortDigits = digits.filterIndexed { i, it -> it.length < i } 294 | 295 | Log.d("Short digits:") 296 | shortDigits.forEach { Log.d("The word $it is shorter than its value.") } 297 | } 298 | ``` 299 | #### Output 300 | 301 | Short digits: 302 | The word five is shorter than its value. 303 | The word six is shorter than its value. 304 | The word seven is shorter than its value. 305 | The word eight is shorter than its value. 306 | The word nine is shorter than its value. 307 | 308 | LINQ - Projection Operators 309 | --------------------------- 310 | 311 | ### linq6: Select - Simple 1 312 | ```csharp 313 | //c# 314 | public void Linq6() 315 | { 316 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 317 | 318 | var numsPlusOne = 319 | from n in numbers 320 | select n + 1; 321 | 322 | Console.WriteLine("Numbers + 1:"); 323 | foreach (var i in numsPlusOne) 324 | { 325 | Console.WriteLine(i); 326 | } 327 | } 328 | ``` 329 | ```kotlin 330 | //kotlin 331 | fun linq06() { 332 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 333 | 334 | val numsPlusOne = numbers.map { it + 1 } 335 | 336 | Log.d("Numbers + 1:") 337 | numsPlusOne.forEach { Log.d(it) } 338 | } 339 | ``` 340 | #### Output 341 | 342 | Numbers + 1: 343 | 6 344 | 5 345 | 2 346 | 4 347 | 10 348 | 9 349 | 7 350 | 8 351 | 3 352 | 1 353 | 354 | ### linq7: Select - Simple 2 355 | ```csharp 356 | //c# 357 | public void Linq7() 358 | { 359 | List products = GetProductList(); 360 | 361 | var productNames = 362 | from p in products 363 | select p.ProductName; 364 | 365 | Console.WriteLine("Product Names:"); 366 | foreach (var productName in productNames) 367 | { 368 | Console.WriteLine(productName); 369 | } 370 | } 371 | ``` 372 | ```kotlin 373 | //kotlin 374 | fun linq07() { 375 | val productNames = products.map { it.productName } 376 | 377 | Log.d("Product Names:") 378 | productNames.forEach { Log.d(it) } 379 | } 380 | ``` 381 | #### Output 382 | 383 | Product Names: 384 | Chai 385 | Chang 386 | Aniseed Syrup 387 | Chef Anton's Cajun Seasoning 388 | Chef Anton's Gumbo Mix 389 | ... 390 | 391 | ### linq8: Select - Transformation 392 | ```csharp 393 | //c# 394 | public void Linq8() 395 | { 396 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 397 | string[] strings = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; 398 | 399 | var textNums = 400 | from n in numbers 401 | select strings[n]; 402 | 403 | Console.WriteLine("Number strings:"); 404 | foreach (var s in textNums) 405 | { 406 | Console.WriteLine(s); 407 | } 408 | } 409 | ``` 410 | ```kotlin 411 | //kotlin 412 | fun linq08() { 413 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 414 | val strings = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") 415 | 416 | val textNums = numbers.map { strings[it] } 417 | 418 | Log.d("Number strings:") 419 | textNums.forEach { Log.d(it) } 420 | } 421 | ``` 422 | #### Output 423 | 424 | Number strings: 425 | five 426 | four 427 | one 428 | three 429 | nine 430 | eight 431 | six 432 | seven 433 | two 434 | zero 435 | 436 | ### linq9: Select - Anonymous Types 1 437 | ```csharp 438 | //c# 439 | public void Linq9() 440 | { 441 | string[] words = { "aPPLE", "BlUeBeRrY", "cHeRry" }; 442 | 443 | var upperLowerWords = 444 | from w in words 445 | select new { Upper = w.ToUpper(), Lower = w.ToLower() }; 446 | 447 | foreach (var ul in upperLowerWords) 448 | { 449 | Console.WriteLine("Uppercase: {0}, Lowercase: {1}", ul.Upper, ul.Lower); 450 | } 451 | } 452 | ``` 453 | ```kotlin 454 | //kotlin 455 | fun linq09() { 456 | val words = arrayOf("aPPLE", "BlUeBeRrY", "cHeRry") 457 | 458 | val upperLowerWords = words.map { w -> Pair(w.toUpperCase(), w.toLowerCase()) } 459 | 460 | upperLowerWords.forEach { Log.d("Uppercase: ${it.first}, Lowercase: ${it.second}") } 461 | } 462 | ``` 463 | #### Output 464 | 465 | Uppercase: APPLE, Lowercase: apple 466 | Uppercase: BLUEBERRY, Lowercase: blueberry 467 | Uppercase: CHERRY, Lowercase: cherry 468 | 469 | ### linq10: Select - Anonymous Types 2 470 | ```csharp 471 | //c# 472 | public void Linq10() 473 | { 474 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 475 | string[] strings = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; 476 | 477 | var digitOddEvens = 478 | from n in numbers 479 | select new { Digit = strings[n], Even = (n % 2 == 0) }; 480 | 481 | foreach (var d in digitOddEvens) 482 | { 483 | Console.WriteLine("The digit {0} is {1}.", d.Digit, d.Even ? "even" : "odd"); 484 | } 485 | } 486 | ``` 487 | ```kotlin 488 | //kotlin 489 | fun linq10() { 490 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 491 | val strings = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") 492 | 493 | val digitOddEvens = numbers.map { Pair(strings[it], it % 2 == 0) } 494 | 495 | digitOddEvens.forEach { 496 | val (d,isEven) = it 497 | Log.d("The digit $d is ${if (isEven) "even" else "odd"}.") 498 | } 499 | } 500 | ``` 501 | #### Output 502 | 503 | The digit five is odd. 504 | The digit four is even. 505 | The digit one is odd. 506 | The digit three is odd. 507 | The digit nine is odd. 508 | The digit eight is even. 509 | The digit six is even. 510 | The digit seven is odd. 511 | The digit two is even. 512 | The digit zero is even. 513 | 514 | ### linq11: Select - Anonymous Types 3 515 | ```csharp 516 | //c# 517 | public void Linq11() 518 | { 519 | List products = GetProductList(); 520 | 521 | var productInfos = 522 | from p in products 523 | select new { p.ProductName, p.Category, Price = p.UnitPrice }; 524 | 525 | Console.WriteLine("Product Info:"); 526 | foreach (var productInfo in productInfos) 527 | { 528 | Console.WriteLine("{0} is in the category {1} and costs {2} per unit.", productInfo.ProductName, productInfo.Category, productInfo.Price); 529 | } 530 | } 531 | ``` 532 | ```kotlin 533 | //kotlin 534 | fun linq11() { 535 | val productInfos = products.map { p -> Triple(p.productName, p.category, p.unitPrice) } 536 | 537 | Log.d("Product Info:") 538 | productInfos.forEach { 539 | val (name,category,cost) = it 540 | Log.d("$name is in the category $category and costs $cost per unit.") 541 | } 542 | } 543 | ``` 544 | #### Output 545 | 546 | Product Info: 547 | Chai is in the category Beverages and costs 18.0 per unit. 548 | Chang is in the category Beverages and costs 19.0 per unit. 549 | Aniseed Syrup is in the category Condiments and costs 10.0 per unit. 550 | ... 551 | 552 | ### linq12: Select - Indexed 553 | ```csharp 554 | //c# 555 | public void Linq12() 556 | { 557 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 558 | 559 | var numsInPlace = numbers.Select((num, index) => new { Num = num, InPlace = (num == index) }); 560 | 561 | Console.WriteLine("Number: In-place?"); 562 | foreach (var n in numsInPlace) 563 | { 564 | Console.WriteLine("{0}: {1}", n.Num, n.InPlace); 565 | } 566 | } 567 | ``` 568 | ```kotlin 569 | //kotlin 570 | fun linq12() { 571 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 572 | 573 | val numsInPlace = numbers.mapIndexed { index, n -> Pair(n, n == index) } 574 | 575 | Log.d("Number: In-place?") 576 | numsInPlace.forEach { Log.d("${it.first.toString()}: ${it.second}") } 577 | } 578 | ``` 579 | #### Output 580 | 581 | Number: In-place? 582 | 5: false 583 | 4: false 584 | 1: false 585 | 3: true 586 | 9: false 587 | 8: false 588 | 6: true 589 | 7: true 590 | 2: false 591 | 0: false 592 | 593 | ### linq13: Select - Filtered 594 | ```csharp 595 | //c# 596 | public void Linq13() 597 | { 598 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 599 | string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; 600 | 601 | var lowNums = 602 | from n in numbers 603 | where n < 5 604 | select digits[n]; 605 | 606 | Console.WriteLine("Numbers < 5:"); 607 | foreach (var num in lowNums) 608 | { 609 | Console.WriteLine(num); 610 | } 611 | } 612 | ``` 613 | ```kotlin 614 | //kotlin 615 | fun linq13() { 616 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 617 | val digits = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") 618 | 619 | val lowNums = numbers.filter { it < 5 }.map { digits[it] } 620 | 621 | Log.d("Numbers < 5:") 622 | lowNums.forEach { Log.d(it) } 623 | } 624 | ``` 625 | #### Output 626 | 627 | Numbers < 5: 628 | four 629 | one 630 | three 631 | two 632 | zero 633 | 634 | ### linq14: SelectMany - Compound from 1 635 | ```csharp 636 | //c# 637 | public void Linq14() 638 | { 639 | int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; 640 | int[] numbersB = { 1, 3, 5, 7, 8 }; 641 | 642 | var pairs = 643 | from a in numbersA 644 | from b in numbersB 645 | where a < b 646 | select new { a, b }; 647 | 648 | Console.WriteLine("Pairs where a < b:"); 649 | foreach (var pair in pairs) 650 | { 651 | Console.WriteLine("{0} is less than {1}", pair.a, pair.b); 652 | } 653 | } 654 | ``` 655 | ```kotlin 656 | //kotlin 657 | fun linq14() { 658 | val numbersA = intArrayOf(0, 2, 4, 5, 6, 8, 9) 659 | val numbersB = intArrayOf(1, 3, 5, 7, 8) 660 | 661 | val pairs = numbersA.flatMap { a -> 662 | numbersB.filter { b -> a < b } 663 | .map { Pair(a, it) } 664 | } 665 | 666 | Log.d("Pairs where a < b:") 667 | pairs.forEach { Log.d("${it.first.toString()} is less than ${it.second}") } 668 | } 669 | ``` 670 | #### Output 671 | 672 | Pairs where a < b: 673 | 0 is less than 1 674 | 0 is less than 3 675 | 0 is less than 5 676 | 0 is less than 7 677 | 0 is less than 8 678 | 2 is less than 3 679 | 2 is less than 5 680 | 2 is less than 7 681 | 2 is less than 8 682 | 4 is less than 5 683 | 4 is less than 7 684 | 4 is less than 8 685 | 5 is less than 7 686 | 5 is less than 8 687 | 6 is less than 7 688 | 6 is less than 8 689 | 690 | ### linq15: SelectMany - Compound from 2 691 | ```csharp 692 | //c# 693 | public void Linq15() 694 | { 695 | List customers = GetCustomerList(); 696 | 697 | var orders = 698 | from c in customers 699 | from o in c.Orders 700 | where o.Total < 500.00M 701 | select new { c.CustomerID, o.OrderID, o.Total }; 702 | 703 | ObjectDumper.Write(orders); 704 | } 705 | ``` 706 | ```kotlin 707 | //kotlin 708 | fun linq15() { 709 | val orders = customers.flatMap { c -> 710 | c.orders.filter { it.total < 500 } 711 | .map { o -> Triple(c.customerId, o.orderId, o.total) } 712 | } 713 | 714 | orders.forEach { Log.d(it) } 715 | } 716 | ``` 717 | #### Output 718 | 719 | (ALFKI, 10702, 330.0) 720 | (ALFKI, 10952, 471.2) 721 | (ANATR, 10308, 88.8) 722 | (ANATR, 10625, 479.75) 723 | ... 724 | 725 | ### linq16: SelectMany - Compound from 3 726 | ```csharp 727 | //c# 728 | public void Linq16() 729 | { 730 | List customers = GetCustomerList(); 731 | 732 | var orders = 733 | from c in customers 734 | from o in c.Orders 735 | where o.OrderDate >= new DateTime(1998, 1, 1) 736 | select new { c.CustomerID, o.OrderID, o.OrderDate }; 737 | 738 | ObjectDumper.Write(orders); 739 | } 740 | ``` 741 | ```kotlin 742 | //kotlin 743 | fun linq16() { 744 | val date = Date(98, 0, 1) //= 1998-01-01 745 | val orders = customers.flatMap { c -> 746 | c.orders.filter { it.orderDate >= date } 747 | .map { o -> Triple(c.customerId, o.orderId, o.orderDate) } 748 | } 749 | 750 | orders.forEach { Log.d(it) } 751 | } 752 | ``` 753 | #### Output 754 | 755 | (ALFKI, 10835, Thu Jan 15 00:00:00 PST 1998) 756 | (ALFKI, 10952, Mon Mar 16 00:00:00 PST 1998) 757 | (ALFKI, 11011, Thu Apr 09 00:00:00 PDT 1998) 758 | (ANATR, 10926, Wed Mar 04 00:00:00 PST 1998) 759 | (ANTON, 10856, Wed Jan 28 00:00:00 PST 1998) 760 | ... 761 | 762 | ### linq17: SelectMany - from Assignment 763 | ```csharp 764 | //c# 765 | public void Linq17() 766 | { 767 | List customers = GetCustomerList(); 768 | 769 | var orders = 770 | from c in customers 771 | from o in c.Orders 772 | where o.Total >= 2000.0M 773 | select new { c.CustomerID, o.OrderID, o.Total }; 774 | 775 | ObjectDumper.Write(orders); 776 | } 777 | ``` 778 | ```kotlin 779 | //kotlin 780 | fun linq17() { 781 | val orders = customers.flatMap { c -> 782 | c.orders.filter { it.total >= 2000 } 783 | .map { o -> Triple(c.customerId, o.orderId, o.total) } 784 | } 785 | 786 | orders.forEach { Log.d(it) } 787 | } 788 | ``` 789 | #### Output 790 | 791 | (ANTON, 10573, 2082.0) 792 | (AROUT, 10558, 2142.9) 793 | (AROUT, 10953, 4441.25) 794 | (BERGS, 10384, 2222.4) 795 | (BERGS, 10524, 3192.65) 796 | ... 797 | 798 | ### linq18: SelectMany - Multiple from 799 | ```csharp 800 | //c# 801 | public void Linq18() 802 | { 803 | List customers = GetCustomerList(); 804 | 805 | DateTime cutoffDate = new DateTime(1997, 1, 1); 806 | 807 | var orders = 808 | from c in customers 809 | where c.Region == "WA" 810 | from o in c.Orders 811 | where o.OrderDate >= cutoffDate 812 | select new { c.CustomerID, o.OrderID }; 813 | 814 | ObjectDumper.Write(orders); 815 | } 816 | ``` 817 | ```kotlin 818 | //kotlin 819 | fun linq18() { 820 | val cutoffDate = Date(97, 0, 1) //1997-01-01 821 | 822 | val orders = customers 823 | .filter { it.region == "WA" }.flatMap { c -> 824 | c.orders.filter { it.orderDate > cutoffDate } 825 | .map { o -> Pair(c.customerId, o.orderId) } 826 | } 827 | 828 | orders.forEach { Log.d(it) } 829 | } 830 | ``` 831 | #### Output 832 | 833 | (LAZYK, 10482) 834 | (LAZYK, 10545) 835 | (TRAIH, 10574) 836 | (TRAIH, 10577) 837 | (TRAIH, 10822) 838 | (WHITC, 10469) 839 | (WHITC, 10483) 840 | (WHITC, 10504) 841 | (WHITC, 10596) 842 | (WHITC, 10693) 843 | (WHITC, 10696) 844 | (WHITC, 10723) 845 | (WHITC, 10740) 846 | (WHITC, 10861) 847 | (WHITC, 10904) 848 | (WHITC, 11032) 849 | (WHITC, 11066) 850 | 851 | ### linq19: SelectMany - Indexed 852 | ```csharp 853 | //c# 854 | public void Linq19() 855 | { 856 | List customers = GetCustomerList(); 857 | 858 | var customerOrders = 859 | customers.SelectMany( 860 | (cust, custIndex) => 861 | cust.Orders.Select(o => "Customer #" + (custIndex + 1) + 862 | " has an order with OrderID " + o.OrderID)); 863 | 864 | ObjectDumper.Write(customerOrders); 865 | } 866 | ``` 867 | ```kotlin 868 | //kotlin 869 | fun linq19() { 870 | var custIndex = 0 871 | val customerOrders = customers.flatMap { c -> 872 | c.orders.mapIndexed { index, o -> "Customer #$index has an order with OrderID ${o.orderId}" } 873 | } 874 | 875 | customerOrders.forEach { Log.d(it) } 876 | } 877 | ``` 878 | #### Output 879 | 880 | Customer #1 has an order with OrderID 10643 881 | Customer #1 has an order with OrderID 10692 882 | Customer #1 has an order with OrderID 10702 883 | Customer #1 has an order with OrderID 10835 884 | Customer #1 has an order with OrderID 10952 885 | Customer #1 has an order with OrderID 11011 886 | Customer #2 has an order with OrderID 10308 887 | Customer #2 has an order with OrderID 10625 888 | Customer #2 has an order with OrderID 10759 889 | Customer #2 has an order with OrderID 10926 890 | ... 891 | 892 | LINQ - Partitioning Operators 893 | ----------------------------- 894 | 895 | ### linq20: Take - Simple 896 | ```csharp 897 | //c# 898 | public void Linq20() 899 | { 900 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 901 | 902 | var first3Numbers = numbers.Take(3); 903 | 904 | Console.WriteLine("First 3 numbers:"); 905 | 906 | foreach (var n in first3Numbers) 907 | { 908 | Console.WriteLine(n); 909 | } 910 | } 911 | ``` 912 | ```kotlin 913 | //kotlin 914 | fun linq20() { 915 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 916 | 917 | val first3Numbers = numbers.take(3) 918 | 919 | Log.d("First 3 numbers:") 920 | first3Numbers.forEach { Log.d(it) } 921 | } 922 | ``` 923 | #### Output 924 | 925 | First 3 numbers: 926 | 5 927 | 4 928 | 1 929 | 930 | ### linq21: Take - Nested 931 | ```csharp 932 | //c# 933 | public void Linq21() 934 | { 935 | List customers = GetCustomerList(); 936 | 937 | var first3WAOrders = ( 938 | from c in customers 939 | from o in c.Orders 940 | where c.Region == "WA" 941 | select new { c.CustomerID, o.OrderID, o.OrderDate }) 942 | .Take(3); 943 | 944 | Console.WriteLine("First 3 orders in WA:"); 945 | foreach (var order in first3WAOrders) 946 | { 947 | ObjectDumper.Write(order); 948 | } 949 | } 950 | ``` 951 | ```kotlin 952 | //kotlin 953 | fun linq21() { 954 | val first3WAOrders = customers 955 | .filter { it.region == "WA" } 956 | .flatMap { c -> 957 | c.orders.map { o -> Triple(c.customerId, o.orderId, o.orderDate) } 958 | } 959 | .take(3) 960 | 961 | Log.d("First 3 orders in WA:") 962 | first3WAOrders.forEach { Log.d(it) } 963 | } 964 | ``` 965 | #### Output 966 | 967 | First 3 orders in WA: 968 | (LAZYK, 10482, Fri Mar 21 00:00:00 PST 1997) 969 | (LAZYK, 10545, Thu May 22 00:00:00 PDT 1997) 970 | (TRAIH, 10574, Thu Jun 19 00:00:00 PDT 1997) 971 | 972 | 973 | ### linq22: Skip - Simple 974 | ```csharp 975 | //c# 976 | public void Linq22() 977 | { 978 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 979 | 980 | var allButFirst4Numbers = numbers.Skip(4); 981 | 982 | Console.WriteLine("All but first 4 numbers:"); 983 | foreach (var n in allButFirst4Numbers) 984 | { 985 | Console.WriteLine(n); 986 | } 987 | } 988 | ``` 989 | ```kotlin 990 | //kotlin 991 | fun linq22() { 992 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 993 | 994 | val allButFirst4Numbers = numbers.drop(4) 995 | 996 | Log.d("All but first 4 numbers:") 997 | allButFirst4Numbers.forEach { Log.d(it) } 998 | } 999 | ``` 1000 | #### Output 1001 | 1002 | All but first 4 numbers: 1003 | 9 1004 | 8 1005 | 6 1006 | 7 1007 | 2 1008 | 0 1009 | 1010 | ### linq23: Skip - Nested 1011 | ```csharp 1012 | //c# 1013 | public void Linq23() 1014 | { 1015 | List customers = GetCustomerList(); 1016 | 1017 | var waOrders = 1018 | from c in customers 1019 | from o in c.Orders 1020 | where c.Region == "WA" 1021 | select new { c.CustomerID, o.OrderID, o.OrderDate }; 1022 | 1023 | var allButFirst2Orders = waOrders.Skip(2); 1024 | 1025 | Console.WriteLine("All but first 2 orders in WA:"); 1026 | foreach (var order in allButFirst2Orders) 1027 | { 1028 | ObjectDumper.Write(order); 1029 | } 1030 | } 1031 | ``` 1032 | ```kotlin 1033 | //kotlin 1034 | fun linq23() { 1035 | val waOrders = customers 1036 | .filter { it.region == "WA" } 1037 | .flatMap { c -> 1038 | c.orders.map { o -> Triple(c.customerId, o.orderId, o.orderDate) } 1039 | } 1040 | 1041 | val allButFirst2Orders = waOrders.drop(2) 1042 | 1043 | Log.d("All but first 2 orders in WA:") 1044 | allButFirst2Orders.forEach { Log.d(it) } 1045 | } 1046 | ``` 1047 | #### Output 1048 | 1049 | All but first 2 orders in WA: 1050 | (TRAIH, 10574, Thu Jun 19 00:00:00 PDT 1997) 1051 | (TRAIH, 10577, Mon Jun 23 00:00:00 PDT 1997) 1052 | (TRAIH, 10822, Thu Jan 08 00:00:00 PST 1998) 1053 | (WHITC, 10269, Wed Jul 31 00:00:00 PDT 1996) 1054 | (WHITC, 10344, Fri Nov 01 00:00:00 PST 1996) 1055 | (WHITC, 10469, Mon Mar 10 00:00:00 PST 1997) 1056 | (WHITC, 10483, Mon Mar 24 00:00:00 PST 1997) 1057 | (WHITC, 10504, Fri Apr 11 00:00:00 PDT 1997) 1058 | (WHITC, 10596, Fri Jul 11 00:00:00 PDT 1997) 1059 | (WHITC, 10693, Mon Oct 06 00:00:00 PDT 1997) 1060 | (WHITC, 10696, Wed Oct 08 00:00:00 PDT 1997) 1061 | (WHITC, 10723, Thu Oct 30 00:00:00 PST 1997) 1062 | (WHITC, 10740, Thu Nov 13 00:00:00 PST 1997) 1063 | (WHITC, 10861, Fri Jan 30 00:00:00 PST 1998) 1064 | (WHITC, 10904, Tue Feb 24 00:00:00 PST 1998) 1065 | (WHITC, 11032, Fri Apr 17 00:00:00 PDT 1998) 1066 | (WHITC, 11066, Fri May 01 00:00:00 PDT 1998) 1067 | 1068 | ### linq24: TakeWhile - Simple 1069 | ```csharp 1070 | //c# 1071 | public void Linq24() 1072 | { 1073 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 1074 | 1075 | var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6); 1076 | 1077 | Console.WriteLine("First numbers less than 6:"); 1078 | foreach (var n in firstNumbersLessThan6) 1079 | { 1080 | Console.WriteLine(n); 1081 | } 1082 | } 1083 | ``` 1084 | ```kotlin 1085 | //kotlin 1086 | fun linq24() { 1087 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 1088 | 1089 | val firstNumbersLessThan6 = numbers.takeWhile { it < 6 } 1090 | 1091 | Log.d("First numbers less than 6:") 1092 | firstNumbersLessThan6.forEach { Log.d(it) } 1093 | } 1094 | ``` 1095 | #### Output 1096 | 1097 | First numbers less than 6: 1098 | 5 1099 | 4 1100 | 1 1101 | 3 1102 | 1103 | ### linq25: TakeWhile - Indexed 1104 | ```csharp 1105 | //c# 1106 | public void Linq25() 1107 | { 1108 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 1109 | 1110 | var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index); 1111 | 1112 | Console.WriteLine("First numbers not less than their position:"); 1113 | foreach (var n in firstSmallNumbers) 1114 | { 1115 | Console.WriteLine(n); 1116 | } 1117 | } 1118 | ``` 1119 | ```kotlin 1120 | //kotlin 1121 | fun linq25() { 1122 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 1123 | 1124 | var index = 0 1125 | val firstSmallNumbers = numbers.takeWhile { it >= index++ } 1126 | 1127 | Log.d("First numbers not less than their position:") 1128 | firstSmallNumbers.forEach { Log.d(it) } 1129 | } 1130 | ``` 1131 | #### Output 1132 | 1133 | First numbers not less than their position: 1134 | 5 1135 | 4 1136 | 1137 | ### linq26: SkipWhile - Simple 1138 | ```csharp 1139 | //c# 1140 | public void Linq26() 1141 | { 1142 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 1143 | 1144 | var allButFirst3Numbers = numbers.SkipWhile(n => n % 3 != 0); 1145 | 1146 | Console.WriteLine("All elements starting from first element divisible by 3:"); 1147 | foreach (var n in allButFirst3Numbers) 1148 | { 1149 | Console.WriteLine(n); 1150 | } 1151 | } 1152 | ``` 1153 | ```kotlin 1154 | //kotlin 1155 | fun linq26() { 1156 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 1157 | 1158 | val allButFirst3Numbers = numbers.dropWhile { it % 3 != 0 } 1159 | 1160 | Log.d("All elements starting from first element divisible by 3:") 1161 | allButFirst3Numbers.forEach { Log.d(it) } 1162 | } 1163 | ``` 1164 | #### Output 1165 | 1166 | All elements starting from first element divisible by 3: 1167 | 3 1168 | 9 1169 | 8 1170 | 6 1171 | 7 1172 | 2 1173 | 0 1174 | 1175 | ### linq27: SkipWhile - Indexed 1176 | ```csharp 1177 | //c# 1178 | public void Linq27() 1179 | { 1180 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 1181 | 1182 | var laterNumbers = numbers.SkipWhile((n, index) => n >= index); 1183 | 1184 | Console.WriteLine("All elements starting from first element less than its position:"); 1185 | foreach (var n in laterNumbers) 1186 | { 1187 | Console.WriteLine(n); 1188 | } 1189 | } 1190 | ``` 1191 | ```kotlin 1192 | //kotlin 1193 | fun linq27() { 1194 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 1195 | 1196 | var index = 0 1197 | val laterNumbers = numbers.dropWhile { it >= index++ } 1198 | 1199 | Log.d("All elements starting from first element less than its position:") 1200 | laterNumbers.forEach { Log.d(it) } 1201 | } 1202 | ``` 1203 | #### Output 1204 | 1205 | All elements starting from first element less than its position: 1206 | 1 1207 | 3 1208 | 9 1209 | 8 1210 | 6 1211 | 7 1212 | 2 1213 | 0 1214 | 1215 | 1216 | LINQ - Ordering Operators 1217 | ------------------------- 1218 | 1219 | ### linq28: OrderBy - Simple 1 1220 | ```csharp 1221 | //c# 1222 | public void Linq28() 1223 | { 1224 | string[] words = { "cherry", "apple", "blueberry" }; 1225 | 1226 | var sortedWords = 1227 | from w in words 1228 | orderby w 1229 | select w; 1230 | 1231 | Console.WriteLine("The sorted list of words:"); 1232 | foreach (var w in sortedWords) 1233 | { 1234 | Console.WriteLine(w); 1235 | } 1236 | } 1237 | ``` 1238 | ```kotlin 1239 | //kotlin 1240 | fun linq28() { 1241 | val words = arrayOf("cherry", "apple", "blueberry") 1242 | 1243 | val sortedWords = words.sorted() 1244 | 1245 | Log.d("The sorted list of words:") 1246 | sortedWords.forEach { Log.d(it) } 1247 | } 1248 | ``` 1249 | #### Output 1250 | 1251 | The sorted list of words: 1252 | apple 1253 | blueberry 1254 | cherry 1255 | 1256 | ### linq29: OrderBy - Simple 2 1257 | ```csharp 1258 | //c# 1259 | public void Linq29() 1260 | { 1261 | string[] words = { "cherry", "apple", "blueberry" }; 1262 | 1263 | var sortedWords = 1264 | from w in words 1265 | orderby w.Length 1266 | select w; 1267 | 1268 | Console.WriteLine("The sorted list of words (by length):"); 1269 | foreach (var w in sortedWords) 1270 | { 1271 | Console.WriteLine(w); 1272 | } 1273 | } 1274 | ``` 1275 | ```kotlin 1276 | //kotlin 1277 | fun linq29() { 1278 | val words = arrayOf("cherry", "apple", "blueberry") 1279 | 1280 | val sortedWords = words.sortedBy { s -> s.length } 1281 | 1282 | Log.d("The sorted list of words (by length):") 1283 | sortedWords.forEach { Log.d(it) } 1284 | } 1285 | ``` 1286 | #### Output 1287 | 1288 | The sorted list of words (by length): 1289 | apple 1290 | cherry 1291 | blueberry 1292 | 1293 | ### linq30: OrderBy - Simple 3 1294 | ```csharp 1295 | //c# 1296 | public void Linq30() 1297 | { 1298 | List products = GetProductList(); 1299 | 1300 | var sortedProducts = 1301 | from p in products 1302 | orderby p.ProductName 1303 | select p; 1304 | 1305 | ObjectDumper.Write(sortedProducts); 1306 | } 1307 | ``` 1308 | ```kotlin 1309 | //kotlin 1310 | fun linq30() { 1311 | val sortedProducts = products.sortedBy { it.productName } 1312 | 1313 | sortedProducts.forEach { Log.d(it) } 1314 | } 1315 | ``` 1316 | #### Output 1317 | 1318 | (Product id=17, name=Alice Mutton, cat=Meat/Poultry, price=39.0, inStock=0) 1319 | (Product id=3, name=Aniseed Syrup, cat=Condiments, price=10.0, inStock=13) 1320 | (Product id=40, name=Boston Crab Meat, cat=Seafood, price=18.4, inStock=123) 1321 | (Product id=60, name=Camembert Pierrot, cat=Dairy Products, price=34.0, inStock=19) 1322 | (Product id=18, name=Carnarvon Tigers, cat=Seafood, price=62.5, inStock=42) 1323 | ... 1324 | 1325 | ### linq31: OrderBy - Comparer 1326 | ```csharp 1327 | //c# 1328 | public void Linq31() 1329 | { 1330 | string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry" }; 1331 | 1332 | var sortedWords = words.OrderBy(a => a, new CaseInsensitiveComparer()); 1333 | 1334 | ObjectDumper.Write(sortedWords); 1335 | } 1336 | ``` 1337 | ```kotlin 1338 | //kotlin 1339 | fun linq31() { 1340 | val words = arrayOf("aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry") 1341 | 1342 | val sortedWords = words.sortedWith(String.CASE_INSENSITIVE_ORDER) 1343 | 1344 | sortedWords.forEach { Log.d(it) } 1345 | } 1346 | ``` 1347 | #### Output 1348 | 1349 | AbAcUs 1350 | aPPLE 1351 | BlUeBeRrY 1352 | bRaNcH 1353 | cHeRry 1354 | ClOvEr 1355 | 1356 | ### linq32: OrderByDescending - Simple 1 1357 | ```csharp 1358 | //c# 1359 | public void Linq32() 1360 | { 1361 | double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 }; 1362 | 1363 | var sortedDoubles = 1364 | from d in doubles 1365 | orderby d descending 1366 | select d; 1367 | 1368 | Console.WriteLine("The doubles from highest to lowest:"); 1369 | foreach (var d in sortedDoubles) 1370 | { 1371 | Console.WriteLine(d); 1372 | } 1373 | } 1374 | ``` 1375 | ```kotlin 1376 | //kotlin 1377 | fun linq32() { 1378 | val doubles = doubleArrayOf(1.7, 2.3, 1.9, 4.1, 2.9) 1379 | 1380 | val sortedDoubles = doubles.sortedDescending() 1381 | 1382 | Log.d("The doubles from highest to lowest:") 1383 | sortedDoubles.forEach { Log.d(it) } 1384 | } 1385 | ``` 1386 | #### Output 1387 | 1388 | The doubles from highest to lowest: 1389 | 4.1 1390 | 2.9 1391 | 2.3 1392 | 1.9 1393 | 1.7 1394 | 1395 | ### linq33: OrderByDescending - Simple 2 1396 | ```csharp 1397 | //c# 1398 | public void Linq33() 1399 | { 1400 | List products = GetProductList(); 1401 | 1402 | var sortedProducts = 1403 | from p in products 1404 | orderby p.UnitsInStock descending 1405 | select p; 1406 | 1407 | ObjectDumper.Write(sortedProducts); 1408 | } 1409 | ``` 1410 | ```kotlin 1411 | //kotlin 1412 | fun linq33() { 1413 | val sortedProducts = products.sortedByDescending { it.unitsInStock } 1414 | 1415 | sortedProducts.forEach { Log.d(it) } 1416 | } 1417 | ``` 1418 | #### Output 1419 | 1420 | (Product id=75, name=Rhönbräu Klosterbier, cat=Beverages, price=7.75, inStock=125) 1421 | (Product id=40, name=Boston Crab Meat, cat=Seafood, price=18.4, inStock=123) 1422 | (Product id=6, name=Grandma's Boysenberry Spread, cat=Condiments, price=25.0, inStock=120) 1423 | (Product id=55, name=Pâté chinois, cat=Meat/Poultry, price=24.0, inStock=115) 1424 | (Product id=61, name=Sirop d'érable, cat=Condiments, price=28.5, inStock=113) 1425 | ... 1426 | 1427 | ### linq34: OrderByDescending - Comparer 1428 | ```csharp 1429 | //c# 1430 | public void Linq34() 1431 | { 1432 | string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry" }; 1433 | 1434 | var sortedWords = words.OrderByDescending(a => a, new CaseInsensitiveComparer()); 1435 | 1436 | ObjectDumper.Write(sortedWords); 1437 | } 1438 | ``` 1439 | ```kotlin 1440 | //kotlin 1441 | fun linq34() { 1442 | val words = arrayOf("aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry") 1443 | 1444 | val sortedWords = words.sortedWith(String.CASE_INSENSITIVE_ORDER).reversed() 1445 | 1446 | sortedWords.forEach { Log.d(it) } 1447 | } 1448 | ``` 1449 | #### Output 1450 | 1451 | ClOvEr 1452 | cHeRry 1453 | bRaNcH 1454 | BlUeBeRrY 1455 | aPPLE 1456 | AbAcUs 1457 | 1458 | ### linq35: ThenBy - Simple 1459 | ```csharp 1460 | //c# 1461 | public void Linq35() 1462 | { 1463 | string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; 1464 | 1465 | var sortedDigits = 1466 | from d in digits 1467 | orderby d.Length, d 1468 | select d; 1469 | 1470 | Console.WriteLine("Sorted digits:"); 1471 | foreach (var d in sortedDigits) 1472 | { 1473 | Console.WriteLine(d); 1474 | } 1475 | } 1476 | ``` 1477 | ```kotlin 1478 | //kotlin 1479 | fun linq35() { 1480 | val digits = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") 1481 | 1482 | val sortedDigits = digits.sorted().sortedBy { it.length } 1483 | 1484 | Log.d("Sorted digits:") 1485 | sortedDigits.forEach { Log.d(it) } 1486 | } 1487 | ``` 1488 | #### Output 1489 | 1490 | Sorted digits: 1491 | one 1492 | six 1493 | two 1494 | five 1495 | four 1496 | nine 1497 | zero 1498 | eight 1499 | seven 1500 | three 1501 | 1502 | ### linq36: ThenBy - Comparer 1503 | ```csharp 1504 | //c# 1505 | public void Linq36() 1506 | { 1507 | string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry" }; 1508 | 1509 | var sortedWords = 1510 | words.OrderBy(a => a.Length) 1511 | .ThenBy(a => a, new CaseInsensitiveComparer()); 1512 | 1513 | ObjectDumper.Write(sortedWords); 1514 | } 1515 | ``` 1516 | ```kotlin 1517 | //kotlin 1518 | fun linq36() { 1519 | val words = arrayOf("aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry") 1520 | 1521 | val sortedWords = words.sortedWith(String.CASE_INSENSITIVE_ORDER).sortedBy { it.length } 1522 | 1523 | sortedWords.forEach { Log.d(it) } 1524 | } 1525 | ``` 1526 | #### Output 1527 | 1528 | aPPLE 1529 | AbAcUs 1530 | bRaNcH 1531 | cHeRry 1532 | ClOvEr 1533 | BlUeBeRrY 1534 | 1535 | ### linq37: ThenByDescending - Simple 1536 | ```csharp 1537 | //c# 1538 | public void Linq37() 1539 | { 1540 | List products = GetProductList(); 1541 | 1542 | var sortedProducts = 1543 | from p in products 1544 | orderby p.Category, p.UnitPrice descending 1545 | select p; 1546 | 1547 | ObjectDumper.Write(sortedProducts); 1548 | } 1549 | ``` 1550 | ```kotlin 1551 | //kotlin 1552 | fun linq37() { 1553 | val sortedProducts = orderByAll(products, 1554 | Comparator { a, b -> a.category.compareTo(b.category) }, 1555 | Comparator { a, b -> b.unitPrice.compareTo(a.unitPrice) }) 1556 | 1557 | sortedProducts.forEach { Log.d(it) } 1558 | } 1559 | ``` 1560 | #### Output 1561 | 1562 | (Product id=38, name=Côte de Blaye, cat=Beverages, price=263.5, inStock=17) 1563 | (Product id=43, name=Ipoh Coffee, cat=Beverages, price=46.0, inStock=17) 1564 | (Product id=2, name=Chang, cat=Beverages, price=19.0, inStock=17) 1565 | (Product id=1, name=Chai, cat=Beverages, price=18.0, inStock=39) 1566 | (Product id=35, name=Steeleye Stout, cat=Beverages, price=18.0, inStock=20) 1567 | (Product id=39, name=Chartreuse verte, cat=Beverages, price=18.0, inStock=69) 1568 | (Product id=76, name=Lakkalikööri, cat=Beverages, price=18.0, inStock=57) 1569 | (Product id=70, name=Outback Lager, cat=Beverages, price=15.0, inStock=15) 1570 | (Product id=34, name=Sasquatch Ale, cat=Beverages, price=14.0, inStock=111) 1571 | ... 1572 | 1573 | ### linq38: ThenByDescending - Comparer 1574 | ```csharp 1575 | //c# 1576 | public void Linq38() 1577 | { 1578 | string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry" }; 1579 | 1580 | var sortedWords = 1581 | words.OrderBy(a => a.Length) 1582 | .ThenByDescending(a => a, new CaseInsensitiveComparer()); 1583 | 1584 | ObjectDumper.Write(sortedWords); 1585 | } 1586 | ``` 1587 | ```kotlin 1588 | //kotlin 1589 | fun linq38() { 1590 | val words = arrayOf("aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry") 1591 | 1592 | val sortedWords = orderByAll(words, 1593 | Comparator { a, b -> Integer.compare(a.length, b.length) }, 1594 | Comparator { a, b -> String.CASE_INSENSITIVE_ORDER.compare(b, a) }) 1595 | 1596 | sortedWords.forEach { Log.d(it) } 1597 | } 1598 | ``` 1599 | #### Output 1600 | 1601 | aPPLE 1602 | ClOvEr 1603 | cHeRry 1604 | bRaNcH 1605 | AbAcUs 1606 | BlUeBeRrY 1607 | 1608 | ### linq39: Reverse 1609 | ```csharp 1610 | //c# 1611 | public void Linq39() 1612 | { 1613 | string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; 1614 | 1615 | var reversedIDigits = ( 1616 | from d in digits 1617 | where d[1] == 'i' 1618 | select d) 1619 | .Reverse(); 1620 | 1621 | Console.WriteLine("A backwards list of the digits with a second character of 'i':"); 1622 | foreach (var d in reversedIDigits) 1623 | { 1624 | Console.WriteLine(d); 1625 | } 1626 | } 1627 | ``` 1628 | ```kotlin 1629 | //kotlin 1630 | fun linq39() { 1631 | val digits = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") 1632 | 1633 | val reversedIDigits = digits.filter { it[1] == 'i' }.reversed() 1634 | 1635 | Log.d("A backwards list of the digits with a second character of 'i':") 1636 | reversedIDigits.forEach { Log.d(it) } 1637 | } 1638 | ``` 1639 | #### Output 1640 | 1641 | A backwards list of the digits with a second character of 'i': 1642 | nine 1643 | eight 1644 | six 1645 | five 1646 | 1647 | 1648 | LINQ - Grouping Operators 1649 | ------------------------- 1650 | 1651 | ### linq40: GroupBy - Simple 1 1652 | ```csharp 1653 | //c# 1654 | public void Linq40() 1655 | { 1656 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 1657 | 1658 | var numberGroups = 1659 | from n in numbers 1660 | group n by n % 5 into g 1661 | select new { Remainder = g.Key, Numbers = g }; 1662 | 1663 | foreach (var g in numberGroups) 1664 | { 1665 | Console.WriteLine("Numbers with a remainder of {0} when divided by 5:", g.Remainder); 1666 | foreach (var n in g.Numbers) 1667 | { 1668 | Console.WriteLine(n); 1669 | } 1670 | } 1671 | } 1672 | ``` 1673 | ```kotlin 1674 | //kotlin 1675 | fun linq40() { 1676 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 1677 | 1678 | val numberGroups = numbers.groupBy { it % 5 } 1679 | .map { Pair(it.key, it) } 1680 | 1681 | numberGroups.forEach { it -> 1682 | val (remainder, g) = it 1683 | Log.d("Numbers with a remainder of $remainder when divided by 5:") 1684 | g.value.forEach { Log.d(it) } 1685 | } 1686 | } 1687 | ``` 1688 | #### Output 1689 | 1690 | Numbers with a remainder of 0 when divided by 5: 1691 | 5 1692 | 0 1693 | Numbers with a remainder of 4 when divided by 5: 1694 | 4 1695 | 9 1696 | Numbers with a remainder of 1 when divided by 5: 1697 | 1 1698 | 6 1699 | Numbers with a remainder of 3 when divided by 5: 1700 | 3 1701 | 8 1702 | Numbers with a remainder of 2 when divided by 5: 1703 | 7 1704 | 2 1705 | 1706 | ### linq41: GroupBy - Simple 2 1707 | ```csharp 1708 | //c# 1709 | public void Linq41() 1710 | { 1711 | string[] words = { "blueberry", "chimpanzee", "abacus", "banana", "apple", "cheese" }; 1712 | 1713 | var wordGroups = 1714 | from w in words 1715 | group w by w[0] into g 1716 | select new { FirstLetter = g.Key, Words = g }; 1717 | 1718 | foreach (var g in wordGroups) 1719 | { 1720 | Console.WriteLine("Words that start with the letter '{0}':", g.FirstLetter); 1721 | foreach (var w in g.Words) 1722 | { 1723 | Console.WriteLine(w); 1724 | } 1725 | } 1726 | } 1727 | ``` 1728 | ```kotlin 1729 | //kotlin 1730 | fun linq41() { 1731 | val words = arrayOf("blueberry", "chimpanzee", "abacus", "banana", "apple", "cheese") 1732 | 1733 | val wordGroups = words.groupBy { it[0] } 1734 | .map { Pair(it.key, it) } 1735 | 1736 | wordGroups.forEach { 1737 | val (firstLetter, g) = it 1738 | Log.d("Words that start with the letter '$firstLetter':") 1739 | g.value.forEach { Log.d(it) } 1740 | } 1741 | } 1742 | ``` 1743 | #### Output 1744 | 1745 | Words that start with the letter 'b': 1746 | blueberry 1747 | banana 1748 | Words that start with the letter 'c': 1749 | chimpanzee 1750 | cheese 1751 | Words that start with the letter 'a': 1752 | abacus 1753 | apple 1754 | 1755 | ### linq42: GroupBy - Simple 3 1756 | ```csharp 1757 | //c# 1758 | public void Linq42() 1759 | { 1760 | List products = GetProductList(); 1761 | 1762 | var orderGroups = 1763 | from p in products 1764 | group p by p.Category into g 1765 | select new { Category = g.Key, Products = g }; 1766 | 1767 | ObjectDumper.Write(orderGroups, 1); 1768 | } 1769 | ``` 1770 | ```kotlin 1771 | //kotlin 1772 | fun linq42() { 1773 | val orderGroups = products.groupBy { it.category } 1774 | .map { Pair(it.key, it) } 1775 | 1776 | orderGroups.forEach { 1777 | val (category,g) = it 1778 | Log.d("${category}:") 1779 | g.value.forEach { Log.d(it) } 1780 | } 1781 | } 1782 | ``` 1783 | #### Output 1784 | 1785 | Beverages: 1786 | (Product id=1, name=Chai, cat=Beverages, price=18.0, inStock=39) 1787 | (Product id=2, name=Chang, cat=Beverages, price=19.0, inStock=17) 1788 | (Product id=24, name=Guaraná Fantástica, cat=Beverages, price=4.5, inStock=20) 1789 | (Product id=34, name=Sasquatch Ale, cat=Beverages, price=14.0, inStock=111) 1790 | (Product id=35, name=Steeleye Stout, cat=Beverages, price=18.0, inStock=20) 1791 | (Product id=38, name=Côte de Blaye, cat=Beverages, price=263.5, inStock=17) 1792 | (Product id=39, name=Chartreuse verte, cat=Beverages, price=18.0, inStock=69) 1793 | (Product id=43, name=Ipoh Coffee, cat=Beverages, price=46.0, inStock=17) 1794 | (Product id=67, name=Laughing Lumberjack Lager, cat=Beverages, price=14.0, inStock=52) 1795 | (Product id=70, name=Outback Lager, cat=Beverages, price=15.0, inStock=15) 1796 | (Product id=75, name=Rhönbräu Klosterbier, cat=Beverages, price=7.75, inStock=125) 1797 | (Product id=76, name=Lakkalikööri, cat=Beverages, price=18.0, inStock=57) 1798 | Condiments: 1799 | (Product id=3, name=Aniseed Syrup, cat=Condiments, price=10.0, inStock=13) 1800 | (Product id=4, name=Chef Anton's Cajun Seasoning, cat=Condiments, price=22.0, inStock=53) 1801 | 1802 | ### linq43: GroupBy - Nested 1803 | ```csharp 1804 | //c# 1805 | public void Linq43() 1806 | { 1807 | List customers = GetCustomerList(); 1808 | 1809 | var customerOrderGroups = 1810 | from c in customers 1811 | select 1812 | new 1813 | { 1814 | c.CompanyName, 1815 | YearGroups = 1816 | from o in c.Orders 1817 | group o by o.OrderDate.Year into yg 1818 | select 1819 | new 1820 | { 1821 | Year = yg.Key, 1822 | MonthGroups = 1823 | from o in yg 1824 | group o by o.OrderDate.Month into mg 1825 | select new { Month = mg.Key, Orders = mg } 1826 | } 1827 | }; 1828 | 1829 | ObjectDumper.Write(customerOrderGroups, 3); 1830 | } 1831 | ``` 1832 | ```kotlin 1833 | //kotlin 1834 | fun linq43() { 1835 | val customerOrderGroups = customers.map { c -> 1836 | Pair(c.companyName, 1837 | c.orders.groupBy { it.orderDate.year + 1900 } 1838 | .map { Pair(it.key, it.value.groupBy { it.orderDate.month + 1 }) }) 1839 | } 1840 | 1841 | customerOrderGroups.forEach { 1842 | val (companyName, yearGroups) = it 1843 | Log.d("\n# $companyName") 1844 | yearGroups.forEach { 1845 | val (year,monthGroups) = it 1846 | Log.d("${year.toString()}: ") 1847 | monthGroups.forEach { Log.d(" $it") } 1848 | } 1849 | } 1850 | } 1851 | ``` 1852 | #### Output 1853 | 1854 | # Alfreds Futterkiste 1855 | 1997: 1856 | 8=[(Order id=10643, total=814.5)] 1857 | 10=[(Order id=10692, total=878.0), (Order id=10702, total=330.0)] 1858 | 1998: 1859 | 1=[(Order id=10835, total=845.8)] 1860 | 3=[(Order id=10952, total=471.2)] 1861 | 4=[(Order id=11011, total=933.5)] 1862 | 1863 | ### linq44: GroupBy - Comparer 1864 | ```csharp 1865 | //c# 1866 | public void Linq44() 1867 | { 1868 | string[] anagrams = { "from ", " salt", " earn ", " last ", " near ", " form " }; 1869 | 1870 | var orderGroups = anagrams.GroupBy(w => w.Trim(), new AnagramEqualityComparer()); 1871 | 1872 | ObjectDumper.Write(orderGroups, 1); 1873 | } 1874 | ``` 1875 | ```kotlin 1876 | //kotlin 1877 | fun linq44() { 1878 | val anagrams = listOf("from ", " salt", " earn ", " last ", " near ", " form ") 1879 | 1880 | val orderGroups = groupBy(anagrams, 1881 | { w -> w.trim { it <= ' ' } }, 1882 | { a, b -> 1883 | val aChars = a.toCharArray() 1884 | val bChars = b.toCharArray() 1885 | Arrays.sort(aChars) 1886 | Arrays.sort(bChars) 1887 | Arrays.equals(aChars, bChars) 1888 | }) 1889 | 1890 | orderGroups.forEach { g -> 1891 | val sb = StringBuilder() 1892 | g.forEach { w -> 1893 | if (sb.length > 0) 1894 | sb.append(", ") 1895 | sb.append("'").append(w).append("'") 1896 | } 1897 | Log.d("[ $sb ]") 1898 | } 1899 | } 1900 | ``` 1901 | #### Output 1902 | 1903 | [ ' earn ', ' near ' ] 1904 | [ ' salt', ' last ' ] 1905 | [ 'from ', ' form ' ] 1906 | 1907 | ### linq45: GroupBy - Comparer, Mapped 1908 | ```csharp 1909 | //c# 1910 | public void Linq45() 1911 | { 1912 | string[] anagrams = { "from ", " salt", " earn ", " last ", " near ", " form " }; 1913 | 1914 | var orderGroups = anagrams.GroupBy( 1915 | w => w.Trim(), 1916 | a => a.ToUpper(), 1917 | new AnagramEqualityComparer() 1918 | ); 1919 | 1920 | ObjectDumper.Write(orderGroups, 1); 1921 | } 1922 | ``` 1923 | ```kotlin 1924 | //kotlin 1925 | fun linq45() { 1926 | val anagrams = listOf("from ", " salt", " earn ", " last ", " near ", " form ") 1927 | 1928 | val orderGroups = groupBy(anagrams, 1929 | { w -> w.trim { it <= ' ' } }, 1930 | { a, b -> 1931 | val aChars = a.toCharArray() 1932 | val bChars = b.toCharArray() 1933 | Arrays.sort(aChars) 1934 | Arrays.sort(bChars) 1935 | Arrays.equals(aChars, bChars) 1936 | }, 1937 | { it.toUpperCase() }) 1938 | 1939 | orderGroups.forEach { g -> 1940 | val sb = StringBuilder() 1941 | g.forEach { 1942 | if (sb.length > 0) 1943 | sb.append(", ") 1944 | sb.append("'").append(it).append("'") 1945 | } 1946 | Log.d("[ $sb ]") 1947 | } 1948 | } 1949 | ``` 1950 | #### Output 1951 | 1952 | [ ' EARN ', ' NEAR ' ] 1953 | [ ' SALT', ' LAST ' ] 1954 | [ 'FROM ', ' FORM ' ] 1955 | 1956 | 1957 | LINQ - Set Operators 1958 | -------------------- 1959 | 1960 | ### linq46: Distinct - 1 1961 | ```csharp 1962 | //c# 1963 | public void Linq46() 1964 | { 1965 | int[] factorsOf300 = { 2, 2, 3, 5, 5 }; 1966 | 1967 | var uniqueFactors = factorsOf300.Distinct(); 1968 | 1969 | Console.WriteLine("Prime factors of 300:"); 1970 | foreach (var f in uniqueFactors) 1971 | { 1972 | Console.WriteLine(f); 1973 | } 1974 | } 1975 | ``` 1976 | ```kotlin 1977 | //kotlin 1978 | fun linq46() { 1979 | val factorsOf300 = intArrayOf(2, 2, 3, 5, 5) 1980 | 1981 | val uniqueFactors = factorsOf300.distinct() 1982 | 1983 | Log.d("Prime factors of 300:") 1984 | uniqueFactors.forEach { Log.d(it) } 1985 | } 1986 | ``` 1987 | #### Output 1988 | 1989 | Prime factors of 300: 1990 | 2 1991 | 3 1992 | 5 1993 | 1994 | ### linq47: Distinct - 2 1995 | ```csharp 1996 | //c# 1997 | public void Linq47() 1998 | { 1999 | List products = GetProductList(); 2000 | 2001 | var categoryNames = ( 2002 | from p in products 2003 | select p.Category) 2004 | .Distinct(); 2005 | 2006 | Console.WriteLine("Category names:"); 2007 | foreach (var n in categoryNames) 2008 | { 2009 | Console.WriteLine(n); 2010 | } 2011 | } 2012 | ``` 2013 | ```kotlin 2014 | //kotlin 2015 | fun linq47() { 2016 | val categoryNames = products.map { it.category}.distinct() 2017 | 2018 | Log.d("Category names:") 2019 | categoryNames.forEach { Log.d(it) } 2020 | } 2021 | ``` 2022 | #### Output 2023 | 2024 | Category names: 2025 | Beverages 2026 | Condiments 2027 | Produce 2028 | Meat/Poultry 2029 | Seafood 2030 | Dairy Products 2031 | Confections 2032 | Grains/Cereals 2033 | 2034 | ### linq48: Union - 1 2035 | ```csharp 2036 | //c# 2037 | public void Linq48() 2038 | { 2039 | int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; 2040 | int[] numbersB = { 1, 3, 5, 7, 8 }; 2041 | 2042 | var uniqueNumbers = numbersA.Union(numbersB); 2043 | 2044 | Console.WriteLine("Unique numbers from both arrays:"); 2045 | foreach (var n in uniqueNumbers) 2046 | { 2047 | Console.WriteLine(n); 2048 | } 2049 | } 2050 | ``` 2051 | ```kotlin 2052 | //kotlin 2053 | fun linq48() { 2054 | val numbersA = listOf(0, 2, 4, 5, 6, 8, 9) 2055 | val numbersB = listOf(1, 3, 5, 7, 8) 2056 | 2057 | val uniqueNumbers = numbersA.union(numbersB) 2058 | 2059 | Log.d("Unique numbers from both arrays:") 2060 | uniqueNumbers.forEach { Log.d(it) } 2061 | } 2062 | ``` 2063 | #### Output 2064 | 2065 | Unique numbers from both arrays: 2066 | 0 2067 | 2 2068 | 4 2069 | 5 2070 | 6 2071 | 8 2072 | 9 2073 | 1 2074 | 3 2075 | 7 2076 | 2077 | ### linq49: Union - 2 2078 | ```csharp 2079 | //c# 2080 | public void Linq49() 2081 | { 2082 | List products = GetProductList(); 2083 | List customers = GetCustomerList(); 2084 | 2085 | var productFirstChars = 2086 | from p in products 2087 | select p.ProductName[0]; 2088 | var customerFirstChars = 2089 | from c in customers 2090 | select c.CompanyName[0]; 2091 | 2092 | var uniqueFirstChars = productFirstChars.Union(customerFirstChars); 2093 | 2094 | Console.WriteLine("Unique first letters from Product names and Customer names:"); 2095 | foreach (var ch in uniqueFirstChars) 2096 | { 2097 | Console.WriteLine(ch); 2098 | } 2099 | } 2100 | ``` 2101 | ```kotlin 2102 | //kotlin 2103 | fun linq49() { 2104 | val productFirstChars = products.map { it.productName[0] } 2105 | 2106 | val customerFirstChars = customers.map { it.companyName[0] } 2107 | 2108 | val uniqueFirstChars = productFirstChars.union(customerFirstChars) 2109 | 2110 | Log.d("Unique first letters from Product names and Customer names:") 2111 | uniqueFirstChars.forEach { Log.d(it) } 2112 | } 2113 | ``` 2114 | #### Output 2115 | 2116 | Unique first letters from Product names and Customer names: 2117 | C 2118 | A 2119 | G 2120 | U 2121 | N 2122 | M 2123 | I 2124 | Q 2125 | K 2126 | T 2127 | P 2128 | S 2129 | R 2130 | B 2131 | J 2132 | Z 2133 | V 2134 | F 2135 | E 2136 | W 2137 | L 2138 | O 2139 | D 2140 | H 2141 | 2142 | ### linq50: Intersect - 1 2143 | ```csharp 2144 | //c# 2145 | public void Linq50() 2146 | { 2147 | int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; 2148 | int[] numbersB = { 1, 3, 5, 7, 8 }; 2149 | 2150 | var commonNumbers = numbersA.Intersect(numbersB); 2151 | 2152 | Console.WriteLine("Common numbers shared by both arrays:"); 2153 | foreach (var n in commonNumbers) 2154 | { 2155 | Console.WriteLine(n); 2156 | } 2157 | } 2158 | ``` 2159 | ```kotlin 2160 | //kotlin 2161 | fun linq50() { 2162 | val numbersA = listOf(0, 2, 4, 5, 6, 8, 9) 2163 | val numbersB = listOf(1, 3, 5, 7, 8) 2164 | 2165 | val commonNumbers = numbersA.intersect(numbersB) 2166 | 2167 | Log.d("Common numbers shared by both arrays:") 2168 | commonNumbers.forEach { Log.d(it) } 2169 | } 2170 | ``` 2171 | #### Output 2172 | 2173 | Common numbers shared by both arrays: 2174 | 5 2175 | 8 2176 | 2177 | ### linq51: Intersect - 2 2178 | ```csharp 2179 | //c# 2180 | public void Linq51() 2181 | { 2182 | List products = GetProductList(); 2183 | List customers = GetCustomerList(); 2184 | 2185 | var productFirstChars = 2186 | from p in products 2187 | select p.ProductName[0]; 2188 | var customerFirstChars = 2189 | from c in customers 2190 | select c.CompanyName[0]; 2191 | 2192 | var commonFirstChars = productFirstChars.Intersect(customerFirstChars); 2193 | 2194 | Console.WriteLine("Common first letters from Product names and Customer names:"); 2195 | foreach (var ch in commonFirstChars) 2196 | { 2197 | Console.WriteLine(ch); 2198 | } 2199 | } 2200 | ``` 2201 | ```kotlin 2202 | //kotlin 2203 | fun linq51() { 2204 | val productFirstChars = products.map { it.productName[0] } 2205 | 2206 | val customerFirstChars = customers.map { it.companyName[0] } 2207 | 2208 | val commonFirstChars = productFirstChars.intersect(customerFirstChars) 2209 | 2210 | Log.d("Common first letters from Product names and Customer names:") 2211 | commonFirstChars.forEach { Log.d(it) } 2212 | } 2213 | ``` 2214 | #### Output 2215 | 2216 | Common first letters from Product names and Customer names: 2217 | C 2218 | A 2219 | G 2220 | N 2221 | M 2222 | I 2223 | Q 2224 | K 2225 | T 2226 | P 2227 | S 2228 | R 2229 | B 2230 | V 2231 | F 2232 | E 2233 | W 2234 | L 2235 | O 2236 | 2237 | ### linq52: Except - 1 2238 | ```csharp 2239 | //c# 2240 | public void Linq52() 2241 | { 2242 | int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; 2243 | int[] numbersB = { 1, 3, 5, 7, 8 }; 2244 | 2245 | IEnumerable aOnlyNumbers = numbersA.Except(numbersB); 2246 | 2247 | Console.WriteLine("Numbers in first array but not second array:"); 2248 | foreach (var n in aOnlyNumbers) 2249 | { 2250 | Console.WriteLine(n); 2251 | } 2252 | } 2253 | ``` 2254 | ```kotlin 2255 | //kotlin 2256 | fun linq52() { 2257 | val numbersA = listOf(0, 2, 4, 5, 6, 8, 9) 2258 | val numbersB = listOf(1, 3, 5, 7, 8) 2259 | 2260 | val aOnlyNumbers = numbersA.difference(numbersB) 2261 | 2262 | Log.d("Numbers in first array but not second array:") 2263 | aOnlyNumbers.forEach { Log.d(it) } 2264 | } 2265 | ``` 2266 | #### Output 2267 | 2268 | Numbers in first array but not second array: 2269 | 0 2270 | 2 2271 | 4 2272 | 6 2273 | 9 2274 | 2275 | ### linq53: Except - 2 2276 | ```csharp 2277 | //c# 2278 | public void Linq53() 2279 | { 2280 | List products = GetProductList(); 2281 | List customers = GetCustomerList(); 2282 | 2283 | var productFirstChars = 2284 | from p in products 2285 | select p.ProductName[0]; 2286 | var customerFirstChars = 2287 | from c in customers 2288 | select c.CompanyName[0]; 2289 | 2290 | var productOnlyFirstChars = productFirstChars.Except(customerFirstChars); 2291 | 2292 | Console.WriteLine("First letters from Product names, but not from Customer names:"); 2293 | foreach (var ch in productOnlyFirstChars) 2294 | { 2295 | Console.WriteLine(ch); 2296 | } 2297 | } 2298 | ``` 2299 | ```kotlin 2300 | //kotlin 2301 | fun linq53() { 2302 | val productFirstChars = products.map { it.productName[0] } 2303 | 2304 | val customerFirstChars = customers.map { it.companyName[0] } 2305 | 2306 | val productOnlyFirstChars = productFirstChars.difference(customerFirstChars) 2307 | 2308 | Log.d("First letters from Product names, but not from Customer names:") 2309 | productOnlyFirstChars.forEach { Log.d(it) } 2310 | } 2311 | ``` 2312 | #### Output 2313 | 2314 | First letters from Product names, but not from Customer names: 2315 | U 2316 | J 2317 | Z 2318 | 2319 | 2320 | LINQ - Conversion Operators 2321 | --------------------------- 2322 | 2323 | ### linq54: ToArray 2324 | ```csharp 2325 | //c# 2326 | public void Linq54() 2327 | { 2328 | double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 }; 2329 | 2330 | var sortedDoubles = 2331 | from d in doubles 2332 | orderby d descending 2333 | select d; 2334 | var doublesArray = sortedDoubles.ToArray(); 2335 | 2336 | Console.WriteLine("Every other double from highest to lowest:"); 2337 | for (int d = 0; d < doublesArray.Length; d += 2) 2338 | { 2339 | Console.WriteLine(doublesArray[d]); 2340 | } 2341 | } 2342 | ``` 2343 | ```kotlin 2344 | //kotlin 2345 | fun linq54() { 2346 | val doubles = doubleArrayOf(1.7, 2.3, 1.9, 4.1, 2.9) 2347 | 2348 | val sortedDoubles = doubles.sortedDescending() 2349 | 2350 | val doublesArray = sortedDoubles.toDoubleArray() 2351 | 2352 | Log.d("Every other double from highest to lowest:") 2353 | var d = 0 2354 | while (d < doublesArray.size) { 2355 | Log.d(doublesArray[d]) 2356 | d += 2 2357 | } 2358 | } 2359 | ``` 2360 | #### Output 2361 | 2362 | Every other double from highest to lowest: 2363 | 4.1 2364 | 2.3 2365 | 1.7 2366 | 2367 | ### linq55: ToList 2368 | ```csharp 2369 | //c# 2370 | public void Linq55() 2371 | { 2372 | string[] words = { "cherry", "apple", "blueberry" }; 2373 | 2374 | var sortedWords = 2375 | from w in words 2376 | orderby w 2377 | select w; 2378 | var wordList = sortedWords.ToList(); 2379 | 2380 | Console.WriteLine("The sorted word list:"); 2381 | foreach (var w in wordList) 2382 | { 2383 | Console.WriteLine(w); 2384 | } 2385 | } 2386 | ``` 2387 | ```kotlin 2388 | //kotlin 2389 | fun linq55() { 2390 | val words = arrayOf("cherry", "apple", "blueberry") 2391 | 2392 | val sortedWords = words.sorted() 2393 | val wordList = sortedWords.toList() 2394 | 2395 | Log.d("The sorted word list:") 2396 | wordList.forEach { Log.d(it) } 2397 | } 2398 | ``` 2399 | #### Output 2400 | 2401 | The sorted word list: 2402 | apple 2403 | blueberry 2404 | cherry 2405 | 2406 | ### linq56: ToDictionary 2407 | ```csharp 2408 | //c# 2409 | public void Linq56() 2410 | { 2411 | var scoreRecords = new[] { new {Name = "Alice", Score = 50}, 2412 | new {Name = "Bob" , Score = 40}, 2413 | new {Name = "Cathy", Score = 45} 2414 | }; 2415 | 2416 | var scoreRecordsDict = scoreRecords.ToDictionary(sr => sr.Name); 2417 | 2418 | Console.WriteLine("Bob's score: {0}", scoreRecordsDict["Bob"]); 2419 | } 2420 | ``` 2421 | ```kotlin 2422 | //kotlin 2423 | fun linq56() { 2424 | val scoreRecords = listOf( 2425 | Pair("Alice", 50), 2426 | Pair("Bob", 40), 2427 | Pair("Cathy", 45) 2428 | ) 2429 | 2430 | val scoreRecordsDict = scoreRecords.toMap() 2431 | 2432 | Log.d("Bob's score: ${scoreRecordsDict["Bob"]}") 2433 | } 2434 | ``` 2435 | #### Output 2436 | 2437 | Bob's score: 40 2438 | 2439 | ### linq57: OfType 2440 | ```csharp 2441 | //c# 2442 | public void Linq57() 2443 | { 2444 | object[] numbers = { null, 1.0, "two", 3, "four", 5, "six", 7.0 }; 2445 | 2446 | var doubles = numbers.OfType(); 2447 | 2448 | Console.WriteLine("Numbers stored as doubles:"); 2449 | foreach (var d in doubles) 2450 | { 2451 | Console.WriteLine(d); 2452 | } 2453 | } 2454 | ``` 2455 | ```kotlin 2456 | //kotlin 2457 | fun linq57() { 2458 | val numbers = arrayOf(null, 1.0, "two", 3, "four", 5, "six", 7.0) 2459 | 2460 | val doubles = numbers.filter { it is Double } 2461 | 2462 | Log.d("Numbers stored as doubles:") 2463 | doubles.forEach { Log.d(it) } 2464 | } 2465 | ``` 2466 | #### Output 2467 | 2468 | Numbers stored as doubles: 2469 | 1.0 2470 | 7.0 2471 | 2472 | 2473 | LINQ - Element Operators 2474 | ------------------------ 2475 | 2476 | ### linq58: First - Simple 2477 | ```csharp 2478 | //c# 2479 | public void Linq58() 2480 | { 2481 | List products = GetProductList(); 2482 | 2483 | Product product12 = ( 2484 | from p in products 2485 | where p.ProductID == 12 2486 | select p) 2487 | .First(); 2488 | 2489 | ObjectDumper.Write(product12); 2490 | } 2491 | ``` 2492 | ```kotlin 2493 | //kotlin 2494 | fun linq58() { 2495 | val product12 = products.filter { it.productId == 12 }.first() 2496 | 2497 | Log.d(product12) 2498 | } 2499 | ``` 2500 | #### Output 2501 | 2502 | (Product id=12, name=Queso Manchego La Pastora, cat=Dairy Products, price=38.0, inStock=86) 2503 | 2504 | ### linq59: First - Condition 2505 | ```csharp 2506 | //c# 2507 | public void Linq59() 2508 | { 2509 | string[] strings = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; 2510 | 2511 | string startsWithO = strings.First(s => s[0] == 'o'); 2512 | 2513 | Console.WriteLine("A string starting with 'o': {0}", startsWithO); 2514 | } 2515 | ``` 2516 | ```kotlin 2517 | //kotlin 2518 | fun linq59() { 2519 | val strings = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") 2520 | 2521 | val startsWithO = strings.first { it[0] == 'o' } 2522 | 2523 | Log.d("A string starting with 'o': $startsWithO") 2524 | } 2525 | ``` 2526 | #### Output 2527 | 2528 | A string starting with 'o': one 2529 | 2530 | ### linq61: FirstOrDefault - Simple 2531 | ```csharp 2532 | //c# 2533 | public void Linq61() 2534 | { 2535 | int[] numbers = { }; 2536 | 2537 | int firstNumOrDefault = numbers.FirstOrDefault(); 2538 | 2539 | Console.WriteLine(firstNumOrDefault); 2540 | } 2541 | ``` 2542 | ```kotlin 2543 | //kotlin 2544 | fun linq61() { 2545 | val numbers = intArrayOf() 2546 | 2547 | val firstNumOrDefault = numbers.firstOrNull() ?: 0 2548 | 2549 | Log.d(firstNumOrDefault) 2550 | } 2551 | ``` 2552 | #### Output 2553 | 2554 | 0 2555 | 2556 | ### linq62: FirstOrDefault - Condition 2557 | ```csharp 2558 | //c# 2559 | public void Linq62() 2560 | { 2561 | List products = GetProductList(); 2562 | 2563 | Product product789 = products.FirstOrDefault(p => p.ProductID == 789); 2564 | 2565 | Console.WriteLine("Product 789 exists: {0}", product789 != null); 2566 | } 2567 | ``` 2568 | ```kotlin 2569 | //kotlin 2570 | fun linq62() { 2571 | val product789 = products.firstOrNull { it.productId == 789 } 2572 | 2573 | Log.d("Product 789 exists: ${product789 != null}") 2574 | } 2575 | ``` 2576 | #### Output 2577 | 2578 | Product 789 exists: false 2579 | 2580 | ### linq64: ElementAt 2581 | ```csharp 2582 | //c# 2583 | public void Linq64() 2584 | { 2585 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 2586 | 2587 | int fourthLowNum = ( 2588 | from n in numbers 2589 | where n > 5 2590 | select n) 2591 | .ElementAt(1); // second number is index 1 because sequences use 0-based indexing 2592 | 2593 | Console.WriteLine("Second number > 5: {0}", fourthLowNum); 2594 | } 2595 | ``` 2596 | ```kotlin 2597 | //kotlin 2598 | fun linq64() { 2599 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 2600 | 2601 | val fourthLowNum = numbers.filter { it > 5 }[1] 2602 | 2603 | Log.d("Second number > 5: $fourthLowNum") 2604 | } 2605 | ``` 2606 | #### Output 2607 | 2608 | Second number > 5: 8 2609 | 2610 | 2611 | LINQ - Generation Operators 2612 | --------------------------- 2613 | 2614 | ### linq65: Range 2615 | ```csharp 2616 | //c# 2617 | public void Linq65() 2618 | { 2619 | var numbers = 2620 | from n in Enumerable.Range(100, 50) 2621 | 2622 | select new { Number = n, OddEven = n % 2 == 1 ? "odd" : "even" }; 2623 | 2624 | foreach (var n in numbers) 2625 | { 2626 | Console.WriteLine("The number {0} is {1}.", n.Number, n.OddEven); 2627 | } 2628 | } 2629 | ``` 2630 | ```kotlin 2631 | //kotlin 2632 | fun linq65() { 2633 | val numbers = (100..150).map { n -> Pair(n, if (n % 2 == 1) "odd" else "even") } 2634 | 2635 | numbers.forEach { Log.d("The number ${it.first} is ${it.second}") } 2636 | } 2637 | ``` 2638 | #### Output 2639 | 2640 | The number 100 is even 2641 | The number 101 is odd 2642 | The number 102 is even 2643 | The number 103 is odd 2644 | The number 104 is even 2645 | The number 105 is odd 2646 | The number 106 is even 2647 | The number 107 is odd 2648 | The number 108 is even 2649 | The number 109 is odd 2650 | The number 110 is even 2651 | ... 2652 | 2653 | ### linq66: Repeat 2654 | ```csharp 2655 | //c# 2656 | public void Linq66() 2657 | { 2658 | var numbers = Enumerable.Repeat(7, 10); 2659 | 2660 | foreach (var n in numbers) 2661 | { 2662 | Console.WriteLine(n); 2663 | } 2664 | } 2665 | ``` 2666 | ```kotlin 2667 | //kotlin 2668 | fun linq66() { 2669 | val numbers = "7".repeat(10) 2670 | 2671 | numbers.forEach { Log.d(it) } 2672 | } 2673 | ``` 2674 | #### Output 2675 | 2676 | 7 2677 | 7 2678 | 7 2679 | 7 2680 | 7 2681 | 7 2682 | 7 2683 | 7 2684 | 7 2685 | 7 2686 | 2687 | 2688 | LINQ - Quantifiers 2689 | ------------------ 2690 | 2691 | ### linq67: Any - Simple 2692 | ```csharp 2693 | //c# 2694 | public void Linq67() 2695 | { 2696 | string[] words = { "believe", "relief", "receipt", "field" }; 2697 | 2698 | bool iAfterE = words.Any(w => w.Contains("ei")); 2699 | 2700 | Console.WriteLine("There is a word that contains in the list that contains 'ei': {0}", iAfterE); 2701 | } 2702 | ``` 2703 | ```kotlin 2704 | //kotlin 2705 | fun linq67() { 2706 | val words = arrayOf("believe", "relief", "receipt", "field") 2707 | 2708 | val iAfterE = words.any { it.contains("ei") } 2709 | 2710 | Log.d("There is a word that contains in the list that contains 'ei': $iAfterE") 2711 | } 2712 | ``` 2713 | #### Output 2714 | 2715 | There is a word that contains in the list that contains 'ei': true 2716 | 2717 | ### linq69: Any - Grouped 2718 | ```csharp 2719 | //c# 2720 | public void Linq69() 2721 | { 2722 | List products = GetProductList(); 2723 | var productGroups = 2724 | from p in products 2725 | group p by p.Category into g 2726 | where g.Any(p => p.UnitsInStock == 0) 2727 | select new { Category = g.Key, Products = g }; 2728 | 2729 | ObjectDumper.Write(productGroups, 1); 2730 | } 2731 | ``` 2732 | ```kotlin 2733 | //kotlin 2734 | fun linq69() { 2735 | val productGroups = products 2736 | .groupBy { it.category } 2737 | .filter { it.value.any { it.unitsInStock == 0 } } 2738 | .map { Pair(it.key, it) } 2739 | 2740 | productGroups.forEach { Log.d(it.second) } 2741 | } 2742 | ``` 2743 | #### Output 2744 | 2745 | Condiments=[(Product id=3, name=Aniseed Syrup, cat=Condiments, price=10.0, inStock=13), (Product id=4, name=Chef Anton's Cajun Seasoning, cat=Condiments, price=22.0, inStock=53), (Product id=5, name=Chef Anton's Gumbo Mix, cat=Condiments, price=21.35, inStock=0), (Product id=6, name=Grandma's Boysenberry Spread, cat=Condiments, price=25.0, inStock=120), (Product id=8, name=Northwoods Cranberry Sauce, cat=Condiments, price=40.0, inStock=6), (Product id=15, name=Genen Shouyu, cat=Condiments, price=15.5, inStock=39), (Product id=44, name=Gula Malacca, cat=Condiments, price=19.45, inStock=27), (Product id=61, name=Sirop d'érable, cat=Condiments, price=28.5, inStock=113), (Product id=63, name=Vegie-spread, cat=Condiments, price=43.9, inStock=24), (Product id=65, name=Louisiana Fiery Hot Pepper Sauce, cat=Condiments, price=21.05, inStock=76), (Product id=66, name=Louisiana Hot Spiced Okra, cat=Condiments, price=17.0, inStock=4), (Product id=77, name=Original Frankfurter grüne Soße, cat=Condiments, price=13.0, inStock=32)] 2746 | Meat/Poultry=[(Product id=9, name=Mishi Kobe Niku, cat=Meat/Poultry, price=97.0, inStock=29), (Product id=17, name=Alice Mutton, cat=Meat/Poultry, price=39.0, inStock=0), (Product id=29, name=Thüringer Rostbratwurst, cat=Meat/Poultry, price=123.79, inStock=0), (Product id=53, name=Perth Pasties, cat=Meat/Poultry, price=32.8, inStock=0), (Product id=54, name=Tourtière, cat=Meat/Poultry, price=7.45, inStock=21), (Product id=55, name=Pâté chinois, cat=Meat/Poultry, price=24.0, inStock=115)] 2747 | Dairy Products=[(Product id=11, name=Queso Cabrales, cat=Dairy Products, price=21.0, inStock=22), (Product id=12, name=Queso Manchego La Pastora, cat=Dairy Products, price=38.0, inStock=86), (Product id=31, name=Gorgonzola Telino, cat=Dairy Products, price=12.5, inStock=0), (Product id=32, name=Mascarpone Fabioli, cat=Dairy Products, price=32.0, inStock=9), (Product id=33, name=Geitost, cat=Dairy Products, price=2.5, inStock=112), (Product id=59, name=Raclette Courdavault, cat=Dairy Products, price=55.0, inStock=79), (Product id=60, name=Camembert Pierrot, cat=Dairy Products, price=34.0, inStock=19), (Product id=69, name=Gudbrandsdalsost, cat=Dairy Products, price=36.0, inStock=26), (Product id=71, name=Flotemysost, cat=Dairy Products, price=21.5, inStock=26), (Product id=72, name=Mozzarella di Giovanni, cat=Dairy Products, price=34.8, inStock=14)] 2748 | ... 2749 | 2750 | ### linq70: All - Simple 2751 | ```csharp 2752 | //c# 2753 | public void Linq70() 2754 | { 2755 | int[] numbers = { 1, 11, 3, 19, 41, 65, 19 }; 2756 | 2757 | bool onlyOdd = numbers.All(n => n % 2 == 1); 2758 | 2759 | Console.WriteLine("The list contains only odd numbers: {0}", onlyOdd); 2760 | } 2761 | ``` 2762 | ```kotlin 2763 | //kotlin 2764 | fun linq70() { 2765 | val numbers = intArrayOf(1, 11, 3, 19, 41, 65, 19) 2766 | 2767 | val onlyOdd = numbers.all { it % 2 == 1 } 2768 | 2769 | Log.d("The list contains only odd numbers: $onlyOdd") 2770 | } 2771 | ``` 2772 | #### Output 2773 | 2774 | The list contains only odd numbers: true 2775 | 2776 | ### linq72: All - Grouped 2777 | ```csharp 2778 | //c# 2779 | public void Linq72() 2780 | { 2781 | List products = GetProductList(); 2782 | 2783 | var productGroups = 2784 | from p in products 2785 | group p by p.Category into g 2786 | where g.All(p => p.UnitsInStock > 0) 2787 | select new { Category = g.Key, Products = g }; 2788 | 2789 | ObjectDumper.Write(productGroups, 1); 2790 | } 2791 | ``` 2792 | ```kotlin 2793 | //kotlin 2794 | fun linq72() { 2795 | val productGroups = products 2796 | .groupBy { it.category } 2797 | .filter { it.value.all { it.unitsInStock > 0 } } 2798 | .map { Pair(it.key, it) } 2799 | 2800 | productGroups.forEach { Log.d(it.second) } 2801 | } 2802 | ``` 2803 | #### Output 2804 | 2805 | Beverages=[(Product id=1, name=Chai, cat=Beverages, price=18.0, inStock=39), (Product id=2, name=Chang, cat=Beverages, price=19.0, inStock=17), (Product id=24, name=Guaraná Fantástica, cat=Beverages, price=4.5, inStock=20), (Product id=34, name=Sasquatch Ale, cat=Beverages, price=14.0, inStock=111), (Product id=35, name=Steeleye Stout, cat=Beverages, price=18.0, inStock=20), (Product id=38, name=Côte de Blaye, cat=Beverages, price=263.5, inStock=17), (Product id=39, name=Chartreuse verte, cat=Beverages, price=18.0, inStock=69), (Product id=43, name=Ipoh Coffee, cat=Beverages, price=46.0, inStock=17), (Product id=67, name=Laughing Lumberjack Lager, cat=Beverages, price=14.0, inStock=52), (Product id=70, name=Outback Lager, cat=Beverages, price=15.0, inStock=15), (Product id=75, name=Rhönbräu Klosterbier, cat=Beverages, price=7.75, inStock=125), (Product id=76, name=Lakkalikööri, cat=Beverages, price=18.0, inStock=57)] 2806 | ... 2807 | 2808 | 2809 | LINQ - Aggregate Operators 2810 | -------------------------- 2811 | 2812 | ### linq73: Count - Simple 2813 | ```csharp 2814 | //c# 2815 | public void Linq73() 2816 | { 2817 | int[] factorsOf300 = { 2, 2, 3, 5, 5 }; 2818 | 2819 | int uniqueFactors = factorsOf300.Distinct().Count(); 2820 | 2821 | Console.WriteLine("There are {0} unique factors of 300.", uniqueFactors); 2822 | } 2823 | ``` 2824 | ```kotlin 2825 | //kotlin 2826 | fun linq73() { 2827 | val factorsOf300 = intArrayOf(2, 2, 3, 5, 5) 2828 | 2829 | val uniqueFactors = factorsOf300.distinct().size 2830 | 2831 | Log.d("There are $uniqueFactors unique factors of 300.") 2832 | } 2833 | ``` 2834 | #### Output 2835 | 2836 | There are 3 unique factors of 300. 2837 | 2838 | ### linq74: Count - Conditional 2839 | ```csharp 2840 | //c# 2841 | public void Linq74() 2842 | { 2843 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 2844 | 2845 | int oddNumbers = numbers.Count(n => n % 2 == 1); 2846 | 2847 | Console.WriteLine("There are {0} odd numbers in the list.", oddNumbers); 2848 | } 2849 | ``` 2850 | ```kotlin 2851 | //kotlin 2852 | fun linq74() { 2853 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 2854 | 2855 | val oddNumbers = numbers.count { it % 2 == 1 } 2856 | 2857 | Log.d("There are $oddNumbers odd numbers in the list.") 2858 | } 2859 | ``` 2860 | #### Output 2861 | 2862 | There are 5 odd numbers in the list. 2863 | 2864 | ### linq76: Count - Nested 2865 | ```csharp 2866 | //c# 2867 | public void Linq76() 2868 | { 2869 | List customers = GetCustomerList(); 2870 | 2871 | var orderCounts = 2872 | from c in customers 2873 | select new { c.CustomerID, OrderCount = c.Orders.Count() }; 2874 | 2875 | ObjectDumper.Write(orderCounts); 2876 | } 2877 | ``` 2878 | ```kotlin 2879 | //kotlin 2880 | fun linq76() { 2881 | val orderCounts = customers.map { Pair(it.customerId, it.orders.size) } 2882 | 2883 | orderCounts.forEach { Log.d(it) } 2884 | } 2885 | ``` 2886 | #### Output 2887 | 2888 | (ALFKI, 6) 2889 | (ANATR, 4) 2890 | (ANTON, 7) 2891 | (AROUT, 13) 2892 | (BERGS, 18) 2893 | (BLAUS, 7) 2894 | (BLONP, 11) 2895 | ... 2896 | 2897 | ### linq77: Count - Grouped 2898 | ```csharp 2899 | //c# 2900 | public void Linq77() 2901 | { 2902 | List products = GetProductList(); 2903 | 2904 | var categoryCounts = 2905 | from p in products 2906 | group p by p.Category into g 2907 | select new { Category = g.Key, ProductCount = g.Count() }; 2908 | 2909 | ObjectDumper.Write(categoryCounts 2910 | } 2911 | ``` 2912 | ```kotlin 2913 | //kotlin 2914 | fun linq77() { 2915 | val categoryCounts = products.groupBy { it.category } 2916 | .map { Pair(it.key, it.value.size) } 2917 | 2918 | categoryCounts.forEach { Log.d(it) } 2919 | } 2920 | ``` 2921 | #### Output 2922 | 2923 | (Beverages, 12) 2924 | (Condiments, 12) 2925 | (Produce, 5) 2926 | (Meat/Poultry, 6) 2927 | (Seafood, 12) 2928 | (Dairy Products, 10) 2929 | (Confections, 13) 2930 | (Grains/Cereals, 7) 2931 | 2932 | ### linq78: Sum - Simple 2933 | ```csharp 2934 | //c# 2935 | public void Linq78() 2936 | { 2937 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 2938 | 2939 | double numSum = numbers.Sum(); 2940 | 2941 | Console.WriteLine("The sum of the numbers is {0}.", numSum); 2942 | } 2943 | ``` 2944 | ```kotlin 2945 | //kotlin 2946 | fun linq78() { 2947 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 2948 | 2949 | val numSum = numbers.sum().toDouble() 2950 | 2951 | Log.d("The sum of the numbers is $numSum") 2952 | } 2953 | ``` 2954 | #### Output 2955 | 2956 | The sum of the numbers is 45.0 2957 | 2958 | ### linq79: Sum - Projection 2959 | ```csharp 2960 | //c# 2961 | public void Linq79() 2962 | { 2963 | string[] words = { "cherry", "apple", "blueberry" }; 2964 | 2965 | double totalChars = words.Sum(w => w.Length); 2966 | 2967 | Console.WriteLine("There are a total of {0} characters in these words.", totalChars); 2968 | } 2969 | ``` 2970 | ```kotlin 2971 | //kotlin 2972 | fun linq79() { 2973 | val words = arrayOf("cherry", "apple", "blueberry") 2974 | 2975 | val totalChars = words.sumOf { it.length } 2976 | 2977 | Log.d("There are a total of $totalChars characters in these words.") 2978 | } 2979 | ``` 2980 | #### Output 2981 | 2982 | There are a total of 20 characters in these words. 2983 | 2984 | ### linq80: Sum - Grouped 2985 | ```csharp 2986 | //c# 2987 | public void Linq80() 2988 | { 2989 | List products = GetProductList(); 2990 | 2991 | var categories = 2992 | from p in products 2993 | group p by p.Category into g 2994 | select new { Category = g.Key, TotalUnitsInStock = g.Sum(p => p.UnitsInStock) }; 2995 | 2996 | ObjectDumper.Write(categories); 2997 | } 2998 | ``` 2999 | ```kotlin 3000 | //kotlin 3001 | fun linq80() { 3002 | val categories = products.groupBy { it.category } 3003 | .map { Pair(it.key, it.value.sumOf { it.unitsInStock }) } 3004 | 3005 | categories.forEach { Log.d(it) } 3006 | } 3007 | ``` 3008 | #### Output 3009 | 3010 | (Beverages, 559) 3011 | (Condiments, 507) 3012 | (Produce, 100) 3013 | (Meat/Poultry, 165) 3014 | (Seafood, 701) 3015 | (Dairy Products, 393) 3016 | (Confections, 386) 3017 | (Grains/Cereals, 308) 3018 | 3019 | ### linq81: Min - Simple 3020 | ```csharp 3021 | //c# 3022 | public void Linq81() 3023 | { 3024 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 3025 | 3026 | int minNum = numbers.Min(); 3027 | 3028 | Console.WriteLine("The minimum number is {0}.", minNum); 3029 | } 3030 | ``` 3031 | ```kotlin 3032 | //kotlin 3033 | fun linq81() { 3034 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 3035 | 3036 | val minNum = numbers.min() 3037 | 3038 | Log.d("The minimum number is $minNum") 3039 | } 3040 | ``` 3041 | #### Output 3042 | 3043 | The minimum number is 0 3044 | 3045 | ### linq82: Min - Projection 3046 | ```csharp 3047 | //c# 3048 | public void Linq82() 3049 | { 3050 | string[] words = { "cherry", "apple", "blueberry" }; 3051 | 3052 | int shortestWord = words.Min(w => w.Length); 3053 | 3054 | Console.WriteLine("The shortest word is {0} characters long.", shortestWord); 3055 | } 3056 | ``` 3057 | ```kotlin 3058 | //kotlin 3059 | fun linq82() { 3060 | val words = arrayOf("cherry", "apple", "blueberry") 3061 | 3062 | val shortestWord = words.minBy { it.length }?.length 3063 | 3064 | Log.d("The shortest word is $shortestWord characters long.") 3065 | } 3066 | ``` 3067 | #### Output 3068 | 3069 | The shortest word is 5 characters long. 3070 | 3071 | ### linq83: Min - Grouped 3072 | ```csharp 3073 | //c# 3074 | public void Linq83() 3075 | { 3076 | List products = GetProductList(); 3077 | 3078 | var categories = 3079 | from p in products 3080 | group p by p.Category into g 3081 | select new { Category = g.Key, CheapestPrice = g.Min(p => p.UnitPrice) }; 3082 | 3083 | ObjectDumper.Write(categories); 3084 | } 3085 | ``` 3086 | ```kotlin 3087 | //kotlin 3088 | fun linq83() { 3089 | val categories = products.groupBy { it.category } 3090 | .map { Pair(it.key, it.value.minBy { it.unitPrice }?.unitPrice) } 3091 | 3092 | categories.forEach { Log.d(it) } 3093 | } 3094 | ``` 3095 | #### Output 3096 | 3097 | (Beverages, 4.5) 3098 | (Condiments, 10.0) 3099 | (Produce, 10.0) 3100 | (Meat/Poultry, 7.45) 3101 | (Seafood, 6.0) 3102 | (Dairy Products, 2.5) 3103 | (Confections, 9.2) 3104 | (Grains/Cereals, 7.0) 3105 | 3106 | ### linq84: Min - Elements 3107 | ```csharp 3108 | //c# 3109 | public void Linq84() 3110 | { 3111 | List products = GetProductList(); 3112 | 3113 | var categories = 3114 | from p in products 3115 | group p by p.Category into g 3116 | let minPrice = g.Min(p => p.UnitPrice) 3117 | select new { Category = g.Key, CheapestProducts = g.Where(p => p.UnitPrice == minPrice) }; 3118 | 3119 | ObjectDumper.Write(categories, 1); 3120 | } 3121 | ``` 3122 | ```kotlin 3123 | //kotlin 3124 | fun linq84() { 3125 | val categories = products.groupBy { it.category } 3126 | .map { 3127 | val minPrice = it.value.minBy { it.unitPrice }!!.unitPrice 3128 | Pair(it.key, it.value.filter { p -> p.unitPrice == minPrice }) 3129 | } 3130 | 3131 | categories.forEach { 3132 | val (category,cheapestProducts) = it 3133 | Log.d(category + ": ") 3134 | cheapestProducts.forEach { Log.d(it) } 3135 | } 3136 | } 3137 | ``` 3138 | #### Output 3139 | 3140 | Beverages: 3141 | (Product id=24, name=Guaraná Fantástica, cat=Beverages, price=4.5, inStock=20) 3142 | Condiments: 3143 | (Product id=3, name=Aniseed Syrup, cat=Condiments, price=10.0, inStock=13) 3144 | Produce: 3145 | (Product id=74, name=Longlife Tofu, cat=Produce, price=10.0, inStock=4) 3146 | Meat/Poultry: 3147 | (Product id=54, name=Tourtière, cat=Meat/Poultry, price=7.45, inStock=21) 3148 | Seafood: 3149 | (Product id=13, name=Konbu, cat=Seafood, price=6.0, inStock=24) 3150 | Dairy Products: 3151 | (Product id=33, name=Geitost, cat=Dairy Products, price=2.5, inStock=112) 3152 | Confections: 3153 | (Product id=19, name=Teatime Chocolate Biscuits, cat=Confections, price=9.2, inStock=25) 3154 | Grains/Cereals: 3155 | (Product id=52, name=Filo Mix, cat=Grains/Cereals, price=7.0, inStock=38) 3156 | 3157 | ### linq85: Max - Simple 3158 | ```csharp 3159 | //c# 3160 | public void Linq85() 3161 | { 3162 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 3163 | 3164 | int maxNum = numbers.Max(); 3165 | 3166 | Console.WriteLine("The maximum number is {0}.", maxNum); 3167 | } 3168 | ``` 3169 | ```kotlin 3170 | //kotlin 3171 | fun linq85() { 3172 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 3173 | 3174 | val maxNum = numbers.max() 3175 | 3176 | Log.d("The maximum number is $maxNum") 3177 | } 3178 | ``` 3179 | #### Output 3180 | 3181 | The maximum number is 9 3182 | 3183 | ### linq86: Max - Projection 3184 | ```csharp 3185 | //c# 3186 | public void Linq86() 3187 | { 3188 | string[] words = { "cherry", "apple", "blueberry" }; 3189 | 3190 | int longestLength = words.Max(w => w.Length); 3191 | 3192 | Console.WriteLine("The longest word is {0} characters long.", longestLength); 3193 | } 3194 | ``` 3195 | ```kotlin 3196 | //kotlin 3197 | fun linq86() { 3198 | val words = arrayOf("cherry", "apple", "blueberry") 3199 | 3200 | val longestLength = words.maxBy { it.length }?.length 3201 | 3202 | Log.d("The longest word is $longestLength characters long.") 3203 | } 3204 | ``` 3205 | #### Output 3206 | 3207 | The longest word is 9 characters long. 3208 | 3209 | ### linq87: Max - Grouped 3210 | ```csharp 3211 | //c# 3212 | public void Linq87() 3213 | { 3214 | List products = GetProductList(); 3215 | 3216 | var categories = 3217 | from p in products 3218 | group p by p.Category into g 3219 | select new { Category = g.Key, MostExpensivePrice = g.Max(p => p.UnitPrice) }; 3220 | 3221 | ObjectDumper.Write(categories); 3222 | } 3223 | ``` 3224 | ```kotlin 3225 | //kotlin 3226 | fun linq87() { 3227 | val categories = products.groupBy { it.category } 3228 | .map { Pair(it.key, it.value.maxBy { it.unitPrice }?.unitPrice) } 3229 | 3230 | categories.forEach { Log.d(it) } 3231 | } 3232 | ``` 3233 | #### Output 3234 | 3235 | (Beverages, 263.5) 3236 | (Condiments, 43.9) 3237 | (Produce, 53.0) 3238 | (Meat/Poultry, 123.79) 3239 | (Seafood, 62.5) 3240 | (Dairy Products, 55.0) 3241 | (Confections, 81.0) 3242 | (Grains/Cereals, 38.0) 3243 | 3244 | ### linq88: Max - Elements 3245 | ```csharp 3246 | //c# 3247 | public void Linq88() 3248 | { 3249 | List products = GetProductList(); 3250 | 3251 | var categories = 3252 | from p in products 3253 | group p by p.Category into g 3254 | let maxPrice = g.Max(p => p.UnitPrice) 3255 | select new { Category = g.Key, MostExpensiveProducts = g.Where(p => p.UnitPrice == maxPrice) }; 3256 | 3257 | ObjectDumper.Write(categories, 1); 3258 | } 3259 | ``` 3260 | ```kotlin 3261 | //kotlin 3262 | fun linq88() { 3263 | val categories = products.groupBy { it.category } 3264 | .map { 3265 | val maxPrice = it.value.maxBy { p -> p.unitPrice }?.unitPrice 3266 | Pair(it.key, it.value.filter { p -> p.unitPrice == maxPrice }) 3267 | } 3268 | 3269 | categories.forEach { 3270 | val (category, mostExpensiveProducts) = it 3271 | Log.d("$category: ") 3272 | mostExpensiveProducts.forEach { Log.d(it) } 3273 | } 3274 | } 3275 | ``` 3276 | #### Output 3277 | 3278 | Beverages: 3279 | (Product id=38, name=Côte de Blaye, cat=Beverages, price=263.5, inStock=17) 3280 | Condiments: 3281 | (Product id=63, name=Vegie-spread, cat=Condiments, price=43.9, inStock=24) 3282 | Produce: 3283 | (Product id=51, name=Manjimup Dried Apples, cat=Produce, price=53.0, inStock=20) 3284 | Meat/Poultry: 3285 | (Product id=29, name=Thüringer Rostbratwurst, cat=Meat/Poultry, price=123.79, inStock=0) 3286 | Seafood: 3287 | (Product id=18, name=Carnarvon Tigers, cat=Seafood, price=62.5, inStock=42) 3288 | Dairy Products: 3289 | (Product id=59, name=Raclette Courdavault, cat=Dairy Products, price=55.0, inStock=79) 3290 | Confections: 3291 | (Product id=20, name=Sir Rodney's Marmalade, cat=Confections, price=81.0, inStock=40) 3292 | Grains/Cereals: 3293 | (Product id=56, name=Gnocchi di nonna Alice, cat=Grains/Cereals, price=38.0, inStock=21) 3294 | 3295 | ### linq89: Average - Simple 3296 | ```csharp 3297 | //c# 3298 | public void Linq89() 3299 | { 3300 | int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 3301 | 3302 | double averageNum = numbers.Average(); 3303 | 3304 | Console.WriteLine("The average number is {0}.", averageNum); 3305 | } 3306 | ``` 3307 | ```kotlin 3308 | //kotlin 3309 | fun linq89() { 3310 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 3311 | 3312 | val averageNum = numbers.average() 3313 | 3314 | Log.d("The average number is $averageNum") 3315 | } 3316 | ``` 3317 | #### Output 3318 | 3319 | The average number is 4.5 3320 | 3321 | ### linq90: Average - Projection 3322 | ```csharp 3323 | //c# 3324 | public void Linq90() 3325 | { 3326 | string[] words = { "cherry", "apple", "blueberry" }; 3327 | 3328 | double averageLength = words.Average(w => w.Length); 3329 | 3330 | Console.WriteLine("The average word length is {0} characters.", averageLength); 3331 | } 3332 | ``` 3333 | ```kotlin 3334 | //kotlin 3335 | fun linq90() { 3336 | val words = arrayOf("cherry", "apple", "blueberry") 3337 | 3338 | val averageLength = words.map { it.length }.average() 3339 | 3340 | Log.d("The average word length is $averageLength characters.") 3341 | } 3342 | ``` 3343 | #### Output 3344 | 3345 | The average word length is 6.666666666666667 characters. 3346 | 3347 | ### linq91: Average - Grouped 3348 | ```csharp 3349 | //c# 3350 | public void Linq91() 3351 | { 3352 | List products = GetProductList(); 3353 | 3354 | var categories = 3355 | from p in products 3356 | group p by p.Category into g 3357 | select new { Category = g.Key, AveragePrice = g.Average(p => p.UnitPrice) }; 3358 | 3359 | ObjectDumper.Write(categories); 3360 | } 3361 | ``` 3362 | ```kotlin 3363 | //kotlin 3364 | fun linq91() { 3365 | val categories = products.groupBy { it.category } 3366 | .map { Pair(it.key, it.value.map{it.unitPrice }.average() ) } 3367 | 3368 | categories.forEach { Log.d("Category: ${it.first}, AveragePrice: ${it.second}") } 3369 | } 3370 | ``` 3371 | #### Output 3372 | 3373 | Category: Beverages, AveragePrice: 37.979166666666664 3374 | Category: Condiments, AveragePrice: 23.0625 3375 | Category: Produce, AveragePrice: 32.37 3376 | Category: Meat/Poultry, AveragePrice: 54.00666666666667 3377 | Category: Seafood, AveragePrice: 20.6825 3378 | Category: Dairy Products, AveragePrice: 28.73 3379 | Category: Confections, AveragePrice: 25.16 3380 | Category: Grains/Cereals, AveragePrice: 20.25 3381 | 3382 | ### linq92: Aggregate - Simple 3383 | ```csharp 3384 | //c# 3385 | public void Linq92() 3386 | { 3387 | double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 }; 3388 | 3389 | double product = doubles.Aggregate((runningProduct, nextFactor) => runningProduct * nextFactor); 3390 | 3391 | Console.WriteLine("Total product of all numbers: {0}", product); 3392 | } 3393 | ``` 3394 | ```kotlin 3395 | //kotlin 3396 | fun linq92() { 3397 | val doubles = doubleArrayOf(1.7, 2.3, 1.9, 4.1, 2.9) 3398 | 3399 | val product = doubles.reduce { runningProduct, nextFactor -> runningProduct * nextFactor } 3400 | 3401 | Log.d("Total product of all numbers: $product") 3402 | } 3403 | ``` 3404 | #### Output 3405 | 3406 | Total product of all numbers: 88.33080999999999 3407 | 3408 | ### linq93: Aggregate - Seed 3409 | ```csharp 3410 | //c# 3411 | public void Linq93() 3412 | { 3413 | double startBalance = 100.0; 3414 | 3415 | int[] attemptedWithdrawals = { 20, 10, 40, 50, 10, 70, 30 }; 3416 | 3417 | double endBalance = 3418 | attemptedWithdrawals.Aggregate(startBalance, 3419 | (balance, nextWithdrawal) => 3420 | ((nextWithdrawal <= balance) ? (balance - nextWithdrawal) : balance)); 3421 | 3422 | Console.WriteLine("Ending balance: {0}", endBalance); 3423 | } 3424 | ``` 3425 | ```kotlin 3426 | //kotlin 3427 | fun linq93() { 3428 | val startBalance = 100 3429 | 3430 | val attemptedWithdrawals = intArrayOf(20, 10, 40, 50, 10, 70, 30) 3431 | 3432 | var i = 0 3433 | val endBalance = attemptedWithdrawals.reduce { acc, nextWithdrawal -> 3434 | val balance = if (i++ == 0 && nextWithdrawal <= acc) startBalance - acc else acc 3435 | if (nextWithdrawal <= balance) balance - nextWithdrawal else balance 3436 | } 3437 | 3438 | Log.d("Ending balance: $endBalance") 3439 | } 3440 | ``` 3441 | #### Output 3442 | 3443 | Ending balance: 20 3444 | 3445 | 3446 | LINQ - Miscellaneous Operators 3447 | ------------------------------ 3448 | 3449 | ### linq94: Concat - 1 3450 | ```csharp 3451 | //c# 3452 | public void Linq94() 3453 | { 3454 | int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; 3455 | int[] numbersB = { 1, 3, 5, 7, 8 }; 3456 | 3457 | var allNumbers = numbersA.Concat(numbersB); 3458 | 3459 | Console.WriteLine("All numbers from both arrays:"); 3460 | foreach (var n in allNumbers) 3461 | { 3462 | Console.WriteLine(n); 3463 | } 3464 | } 3465 | ``` 3466 | ```kotlin 3467 | //kotlin 3468 | fun linq94() { 3469 | val numbersA = intArrayOf(0, 2, 4, 5, 6, 8, 9) 3470 | val numbersB = intArrayOf(1, 3, 5, 7, 8) 3471 | 3472 | val allNumbers = numbersA + numbersB 3473 | 3474 | Log.d("All numbers from both arrays:") 3475 | allNumbers.forEach { Log.d(it) } 3476 | } 3477 | ``` 3478 | #### Output 3479 | 3480 | All numbers from both arrays: 3481 | 0 3482 | 2 3483 | 4 3484 | 5 3485 | 6 3486 | 8 3487 | 9 3488 | 1 3489 | 3 3490 | 5 3491 | 7 3492 | 8 3493 | 3494 | ### linq95: Concat - 2 3495 | ```csharp 3496 | //c# 3497 | public void Linq95() 3498 | { 3499 | List customers = GetCustomerList(); 3500 | List products = GetProductList(); 3501 | 3502 | var customerNames = 3503 | from c in customers 3504 | select c.CompanyName; 3505 | var productNames = 3506 | from p in products 3507 | select p.ProductName; 3508 | 3509 | var allNames = customerNames.Concat(productNames); 3510 | 3511 | Console.WriteLine("Customer and product names:"); 3512 | foreach (var n in allNames) 3513 | { 3514 | Console.WriteLine(n); 3515 | } 3516 | } 3517 | ``` 3518 | ```kotlin 3519 | //kotlin 3520 | fun linq95() { 3521 | val customerNames = customers.map { it.companyName } 3522 | 3523 | val productNames = products.map { it.productName } 3524 | 3525 | val allNames = customerNames + productNames 3526 | 3527 | Log.d("Customer and product names:") 3528 | allNames.forEach { Log.d(it) } 3529 | } 3530 | ``` 3531 | #### Output 3532 | 3533 | Customer and product names: 3534 | Alfreds Futterkiste 3535 | Ana Trujillo Emparedados y helados 3536 | Antonio Moreno Taquería 3537 | Around the Horn 3538 | Berglunds snabbköp 3539 | Blauer See Delikatessen 3540 | ... 3541 | 3542 | ### linq96: EqualAll - 1 3543 | ```csharp 3544 | //c# 3545 | public void Linq96() 3546 | { 3547 | var wordsA = new string[] { "cherry", "apple", "blueberry" }; 3548 | var wordsB = new string[] { "cherry", "apple", "blueberry" }; 3549 | 3550 | bool match = wordsA.SequenceEqual(wordsB); 3551 | 3552 | Console.WriteLine("The sequences match: {0}", match); 3553 | } 3554 | ``` 3555 | ```kotlin 3556 | //kotlin 3557 | fun linq96() { 3558 | val wordsA = arrayOf("cherry", "apple", "blueberry") 3559 | val wordsB = arrayOf("cherry", "apple", "blueberry") 3560 | 3561 | val match = Arrays.equals(wordsA, wordsB) 3562 | 3563 | Log.d("The sequences match: $match") 3564 | } 3565 | ``` 3566 | #### Output 3567 | 3568 | The sequences match: true 3569 | 3570 | ### linq97: EqualAll - 2 3571 | ```csharp 3572 | //c# 3573 | public void Linq97() 3574 | { 3575 | var wordsA = new string[] { "cherry", "apple", "blueberry" }; 3576 | var wordsB = new string[] { "apple", "blueberry", "cherry" }; 3577 | 3578 | bool match = wordsA.SequenceEqual(wordsB); 3579 | 3580 | Console.WriteLine("The sequences match: {0}", match); 3581 | } 3582 | ``` 3583 | ```kotlin 3584 | //kotlin 3585 | fun linq97() { 3586 | val wordsA = arrayOf("cherry", "apple", "blueberry") 3587 | val wordsB = arrayOf("cherry", "blueberry", "cherry") 3588 | 3589 | val match = Arrays.equals(wordsA, wordsB) 3590 | 3591 | Log.d("The sequences match: $match") 3592 | } 3593 | ``` 3594 | #### Output 3595 | 3596 | The sequences match: false 3597 | 3598 | LINQ - Query Execution 3599 | ---------------------- 3600 | 3601 | ### linq99: Deferred Execution 3602 | ```csharp 3603 | //c# 3604 | public void Linq99() 3605 | { 3606 | // Sequence operators form first-class queries that 3607 | // are not executed until you enumerate over them. 3608 | 3609 | int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 3610 | 3611 | int i = 0; 3612 | var q = 3613 | from n in numbers 3614 | select ++i; 3615 | 3616 | // Note, the local variable 'i' is not incremented 3617 | // until each element is evaluated (as a side-effect): 3618 | foreach (var v in q) 3619 | { 3620 | Console.WriteLine("v = {0}, i = {1}", v, i); 3621 | } 3622 | } 3623 | ``` 3624 | ```kotlin 3625 | //kotlin 3626 | fun linq099() { 3627 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 3628 | 3629 | var i = 0 3630 | val q = numbers.map { { ++i } } 3631 | 3632 | for (f in q) { 3633 | val v = f() 3634 | Log.d("v = $v, i = $i") 3635 | } 3636 | } 3637 | ``` 3638 | #### Output 3639 | 3640 | v = 1, i = 1 3641 | v = 2, i = 2 3642 | v = 3, i = 3 3643 | v = 4, i = 4 3644 | v = 5, i = 5 3645 | v = 6, i = 6 3646 | v = 7, i = 7 3647 | v = 8, i = 8 3648 | v = 9, i = 9 3649 | v = 10, i = 10 3650 | 3651 | ### linq100: Immediate Execution 3652 | ```csharp 3653 | //c# 3654 | public void Linq100() 3655 | { 3656 | // Methods like ToList() cause the query to be 3657 | // executed immediately, caching the results. 3658 | 3659 | int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 3660 | 3661 | int i = 0; 3662 | var q = ( 3663 | from n in numbers 3664 | select ++i) 3665 | .ToList(); 3666 | 3667 | // The local variable i has already been fully 3668 | // incremented before we iterate the results: 3669 | foreach (var v in q) 3670 | { 3671 | Console.WriteLine("v = {0}, i = {1}", v, i); 3672 | } 3673 | } 3674 | ``` 3675 | ```kotlin 3676 | //kotlin 3677 | fun linq100() { 3678 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 3679 | 3680 | var i = 0 3681 | val q = numbers.map { ++i } 3682 | 3683 | q.forEach { v -> Log.d("v = $v, i = $i") } 3684 | } 3685 | ``` 3686 | #### Output 3687 | 3688 | v = 1, i = 10 3689 | v = 2, i = 10 3690 | v = 3, i = 10 3691 | v = 4, i = 10 3692 | v = 5, i = 10 3693 | v = 6, i = 10 3694 | v = 7, i = 10 3695 | v = 8, i = 10 3696 | v = 9, i = 10 3697 | v = 10, i = 10 3698 | 3699 | ### linq101: Query Reuse 3700 | ```csharp 3701 | //c# 3702 | public void Linq101() 3703 | { 3704 | // Deferred execution lets us define a query once 3705 | // and then reuse it later after data changes. 3706 | 3707 | int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 3708 | var lowNumbers = 3709 | from n in numbers 3710 | where n <= 3 3711 | select n; 3712 | 3713 | Console.WriteLine("First run numbers <= 3:"); 3714 | foreach (int n in lowNumbers) 3715 | { 3716 | Console.WriteLine(n); 3717 | } 3718 | 3719 | for (int i = 0; i < 10; i++) 3720 | { 3721 | numbers[i] = -numbers[i]; 3722 | } 3723 | 3724 | // During this second run, the same query object, 3725 | // lowNumbers, will be iterating over the new state 3726 | // of numbers[], producing different results: 3727 | Console.WriteLine("Second run numbers <= 3:"); 3728 | foreach (int n in lowNumbers) 3729 | { 3730 | Console.WriteLine(n); 3731 | } 3732 | } 3733 | ``` 3734 | ```kotlin 3735 | //kotlin 3736 | fun linq101() { 3737 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 3738 | 3739 | val lowNumbers = { numbers.filter { n -> n <= 3 } } 3740 | 3741 | Log.d("First run numbers <= 3:") 3742 | lowNumbers().forEach { Log.d(it) } 3743 | 3744 | for (i in 0..9) { 3745 | numbers[i] = -numbers[i] 3746 | } 3747 | 3748 | Log.d("Second run numbers <= 3:") 3749 | lowNumbers().forEach { Log.d(it) } 3750 | } 3751 | ``` 3752 | #### Output 3753 | 3754 | First run numbers <= 3: 3755 | 1 3756 | 3 3757 | 2 3758 | 0 3759 | Second run numbers <= 3: 3760 | -5 3761 | -4 3762 | -1 3763 | -3 3764 | -9 3765 | -8 3766 | -6 3767 | -7 3768 | -2 3769 | 0 3770 | 3771 | 3772 | LINQ - Join Operators 3773 | --------------------- 3774 | 3775 | ### linq102: Cross Join 3776 | ```csharp 3777 | //c# 3778 | public void Linq102() 3779 | { 3780 | string[] categories = new string[]{ 3781 | "Beverages", 3782 | "Condiments", 3783 | "Vegetables", 3784 | "Dairy Products", 3785 | "Seafood" }; 3786 | 3787 | List products = GetProductList(); 3788 | 3789 | var q = 3790 | from c in categories 3791 | join p in products on c equals p.Category 3792 | select new { Category = c, p.ProductName }; 3793 | 3794 | foreach (var v in q) 3795 | { 3796 | Console.WriteLine(v.ProductName + ": " + v.Category); 3797 | } 3798 | } 3799 | ``` 3800 | ```kotlin 3801 | //kotlin 3802 | fun linq102() { 3803 | val categories = listOf("Beverages", "Condiments", "Vegetables", "Dairy Products", "Seafood") 3804 | 3805 | val q = join(categories, products) { c, p -> c == p.category } 3806 | .map { Pair(it.A, it.B.productName) } 3807 | 3808 | q.forEach { Log.d("${it.first}: ${it.second}") } 3809 | } 3810 | ``` 3811 | #### Output 3812 | 3813 | Beverages: Chai 3814 | Beverages: Chang 3815 | Beverages: Guaraná Fantástica 3816 | Beverages: Sasquatch Ale 3817 | Beverages: Steeleye Stout 3818 | Beverages: Côte de Blaye 3819 | Beverages: Chartreuse verte 3820 | Beverages: Ipoh Coffee 3821 | ... 3822 | 3823 | ### linq103: Group Join 3824 | ```csharp 3825 | //c# 3826 | public void Linq103() 3827 | { 3828 | string[] categories = new string[]{ 3829 | "Beverages", 3830 | "Condiments", 3831 | "Vegetables", 3832 | "Dairy Products", 3833 | "Seafood" }; 3834 | 3835 | List products = GetProductList(); 3836 | 3837 | var q = 3838 | from c in categories 3839 | join p in products on c equals p.Category into ps 3840 | select new { Category = c, Products = ps }; 3841 | 3842 | foreach (var v in q) 3843 | { 3844 | Console.WriteLine(v.Category + ":"); 3845 | foreach (var p in v.Products) 3846 | { 3847 | Console.WriteLine(" " + p.ProductName); 3848 | } 3849 | } 3850 | } 3851 | ``` 3852 | ```kotlin 3853 | //kotlin 3854 | fun linq103() { 3855 | val categories = listOf("Beverages", "Condiments", "Vegetables", "Dairy Products", "Seafood") 3856 | 3857 | val q = joinGroup(categories, products) { c, p -> c == p.category } 3858 | .map { Pair(it.key, it.items.map { it.B }) } 3859 | 3860 | q.forEach { 3861 | Log.d("${it.first}:") 3862 | it.second.forEach { p -> Log.d(" ${p.productName}") } 3863 | } 3864 | } 3865 | ``` 3866 | #### Output 3867 | 3868 | Beverages: 3869 | Chai 3870 | Chang 3871 | Guaraná Fantástica 3872 | Sasquatch Ale 3873 | Steeleye Stout 3874 | Côte de Blaye 3875 | Chartreuse verte 3876 | Ipoh Coffee 3877 | Laughing Lumberjack Lager 3878 | Outback Lager 3879 | Rhönbräu Klosterbier 3880 | Lakkalikööri 3881 | Seafood: 3882 | Ikura 3883 | Konbu 3884 | Carnarvon Tigers 3885 | Nord-Ost Matjeshering 3886 | Inlagd Sill 3887 | Gravad lax 3888 | Boston Crab Meat 3889 | Jack's New England Clam Chowder 3890 | Rogede sild 3891 | Spegesild 3892 | Escargots de Bourgogne 3893 | Röd Kaviar 3894 | ... 3895 | 3896 | ### linq104: Cross Join with Group Join 3897 | ```csharp 3898 | //c# 3899 | public void Linq104() 3900 | { 3901 | string[] categories = new string[]{ 3902 | "Beverages", 3903 | "Condiments", 3904 | "Vegetables", 3905 | "Dairy Products", 3906 | "Seafood" }; 3907 | 3908 | List products = GetProductList(); 3909 | 3910 | var q = 3911 | from c in categories 3912 | join p in products on c equals p.Category into ps 3913 | from p in ps 3914 | select new { Category = c, p.ProductName }; 3915 | 3916 | foreach (var v in q) 3917 | { 3918 | Console.WriteLine(v.ProductName + ": " + v.Category); 3919 | } 3920 | } 3921 | ``` 3922 | ```kotlin 3923 | //kotlin 3924 | fun linq104() { 3925 | val categories = listOf("Beverages", "Condiments", "Vegetables", "Dairy Products", "Seafood") 3926 | 3927 | val q = joinGroup(categories, products) { c, p -> c == p.category } 3928 | .flatMap { j -> j.items.map { it.B }.map { Pair(j.key, it.productName) } } 3929 | 3930 | q.forEach { Log.d("${it.second}: ${it.first}") } 3931 | } 3932 | ``` 3933 | #### Output 3934 | 3935 | Chai: Beverages 3936 | Chang: Beverages 3937 | Guaraná Fantástica: Beverages 3938 | Sasquatch Ale: Beverages 3939 | Steeleye Stout: Beverages 3940 | Côte de Blaye: Beverages 3941 | Chartreuse verte: Beverages 3942 | Ipoh Coffee: Beverages 3943 | Laughing Lumberjack Lager: Beverages 3944 | Outback Lager: Beverages 3945 | Rhönbräu Klosterbier: Beverages 3946 | Lakkalikööri: Beverages 3947 | Ikura: Seafood 3948 | Konbu: Seafood 3949 | Carnarvon Tigers: Seafood 3950 | ... 3951 | 3952 | ### linq105: Left Outer Join 3953 | ```csharp 3954 | //c# 3955 | public void Linq105() 3956 | { 3957 | string[] categories = new string[]{ 3958 | "Beverages", 3959 | "Condiments", 3960 | "Vegetables", 3961 | "Dairy Products", 3962 | "Seafood" }; 3963 | 3964 | List products = GetProductList(); 3965 | 3966 | var q = 3967 | from c in categories 3968 | join p in products on c equals p.Category into ps 3969 | from p in ps.DefaultIfEmpty() 3970 | select new { Category = c, ProductName = p == null ? "(No products)" : p.ProductName }; 3971 | 3972 | foreach (var v in q) 3973 | { 3974 | Console.WriteLine(v.ProductName + ": " + v.Category); 3975 | } 3976 | } 3977 | ``` 3978 | ```kotlin 3979 | //kotlin 3980 | fun linq105() { 3981 | val categories = listOf("Beverages", "Condiments", "Vegetables", "Dairy Products", "Seafood") 3982 | 3983 | val q = categories.flatMap { c -> 3984 | val catProducts = products.filter { c == it.category } 3985 | if (catProducts.isEmpty()) 3986 | listOf(Pair(c, "(No products)")) 3987 | else 3988 | catProducts.map { Pair(c, it.productName) } 3989 | } 3990 | 3991 | q.forEach { Log.d("${it.second}: ${it.first}") } 3992 | } 3993 | ``` 3994 | #### Output 3995 | 3996 | Chai: Beverages 3997 | Chang: Beverages 3998 | Guaraná Fantástica: Beverages 3999 | Sasquatch Ale: Beverages 4000 | Steeleye Stout: Beverages 4001 | Côte de Blaye: Beverages 4002 | Chartreuse verte: Beverages 4003 | Ipoh Coffee: Beverages 4004 | Laughing Lumberjack Lager: Beverages 4005 | Outback Lager: Beverages 4006 | Rhönbräu Klosterbier: Beverages 4007 | Lakkalikööri: Beverages 4008 | Aniseed Syrup: Condiments 4009 | Chef Anton's Cajun Seasoning: Condiments 4010 | Chef Anton's Gumbo Mix: Condiments 4011 | Grandma's Boysenberry Spread: Condiments 4012 | Northwoods Cranberry Sauce: Condiments 4013 | Genen Shouyu: Condiments 4014 | Gula Malacca: Condiments 4015 | Sirop d'érable: Condiments 4016 | Vegie-spread: Condiments 4017 | Louisiana Fiery Hot Pepper Sauce: Condiments 4018 | Louisiana Hot Spiced Okra: Condiments 4019 | Original Frankfurter grüne Soße: Condiments 4020 | (No products): Vegetables 4021 | ... 4022 | 4023 | 4024 | ### Contributors 4025 | 4026 | - [mythz](https://github.com/mythz) (Demis Bellot) 4027 | 4028 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /captures 8 | -------------------------------------------------------------------------------- /src/.idea/.name: -------------------------------------------------------------------------------- 1 | KotlinLinqExamples -------------------------------------------------------------------------------- /src/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /src/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /src/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /src/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /src/app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /src/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | 4 | android { 5 | compileSdkVersion 23 6 | buildToolsVersion "21.1.2" 7 | 8 | defaultConfig { 9 | applicationId "servicestack.net.kotlinlinqexamples" 10 | minSdkVersion 19 11 | targetSdkVersion 23 12 | versionCode 1 13 | versionName "1.0" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | sourceSets { 22 | main.java.srcDirs += 'src/main/kotlin' 23 | } 24 | } 25 | 26 | dependencies { 27 | compile fileTree(dir: 'libs', include: ['*.jar']) 28 | compile 'net.servicestack:android:1.0.21' 29 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 30 | } 31 | buildscript { 32 | ext.kotlin_version = '1.0.0-beta-3595' 33 | repositories { 34 | mavenCentral() 35 | } 36 | dependencies { 37 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 38 | } 39 | } 40 | repositories { 41 | mavenCentral() 42 | } 43 | -------------------------------------------------------------------------------- /src/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\mythz\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /src/app/src/androidTest/java/servicestack/net/kotlinlinqexamples/ApplicationTest.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import android.app.Application 4 | import android.test.ApplicationTestCase 5 | 6 | /** 7 | * [Testing Fundamentals](http://d.android.com/tools/testing/testing_android.html) 8 | */ 9 | class ApplicationTest : ApplicationTestCase(Application::class.java) -------------------------------------------------------------------------------- /src/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/AggregateOperators.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import net.servicestack.client.Log 4 | import servicestack.net.kotlinlinqexamples.support.customers 5 | import servicestack.net.kotlinlinqexamples.support.products 6 | 7 | class AggregateOperators { 8 | 9 | fun linq73() { 10 | val factorsOf300 = intArrayOf(2, 2, 3, 5, 5) 11 | 12 | val uniqueFactors = factorsOf300.distinct().size 13 | 14 | Log.d("There are $uniqueFactors unique factors of 300.") 15 | } 16 | 17 | fun linq74() { 18 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 19 | 20 | val oddNumbers = numbers.count { it % 2 == 1 } 21 | 22 | Log.d("There are $oddNumbers odd numbers in the list.") 23 | } 24 | 25 | fun linq76() { 26 | val orderCounts = customers.map { Pair(it.customerId, it.orders.size) } 27 | 28 | orderCounts.forEach { Log.d(it) } 29 | } 30 | 31 | fun linq77() { 32 | val categoryCounts = products.groupBy { it.category } 33 | .map { Pair(it.key, it.value.size) } 34 | 35 | categoryCounts.forEach { Log.d(it) } 36 | } 37 | 38 | fun linq78() { 39 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 40 | 41 | val numSum = numbers.sum().toDouble() 42 | 43 | Log.d("The sum of the numbers is $numSum") 44 | } 45 | 46 | fun linq79() { 47 | val words = arrayOf("cherry", "apple", "blueberry") 48 | 49 | val totalChars = words.sumOf { it.length } 50 | 51 | Log.d("There are a total of $totalChars characters in these words.") 52 | } 53 | 54 | fun linq80() { 55 | val categories = products.groupBy { it.category } 56 | .map { Pair(it.key, it.value.sumOf { it.unitsInStock }) } 57 | 58 | categories.forEach { Log.d(it) } 59 | } 60 | 61 | fun linq81() { 62 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 63 | 64 | val minNum = numbers.min() 65 | 66 | Log.d("The minimum number is $minNum") 67 | } 68 | 69 | fun linq82() { 70 | val words = arrayOf("cherry", "apple", "blueberry") 71 | 72 | val shortestWord = words.minBy { it.length }?.length 73 | 74 | Log.d("The shortest word is $shortestWord characters long.") 75 | } 76 | 77 | fun linq83() { 78 | val categories = products.groupBy { it.category } 79 | .map { Pair(it.key, it.value.minBy { it.unitPrice }?.unitPrice) } 80 | 81 | categories.forEach { Log.d(it) } 82 | } 83 | 84 | fun linq84() { 85 | val categories = products.groupBy { it.category } 86 | .map { 87 | val minPrice = it.value.minBy { it.unitPrice }!!.unitPrice 88 | Pair(it.key, it.value.filter { p -> p.unitPrice == minPrice }) 89 | } 90 | 91 | categories.forEach { 92 | val (category,cheapestProducts) = it 93 | Log.d(category + ": ") 94 | cheapestProducts.forEach { Log.d(it) } 95 | } 96 | } 97 | 98 | fun linq85() { 99 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 100 | 101 | val maxNum = numbers.max() 102 | 103 | Log.d("The maximum number is $maxNum") 104 | } 105 | 106 | fun linq86() { 107 | val words = arrayOf("cherry", "apple", "blueberry") 108 | 109 | val longestLength = words.maxBy { it.length }?.length 110 | 111 | Log.d("The longest word is $longestLength characters long.") 112 | } 113 | 114 | fun linq87() { 115 | val categories = products.groupBy { it.category } 116 | .map { Pair(it.key, it.value.maxBy { it.unitPrice }?.unitPrice) } 117 | 118 | categories.forEach { Log.d(it) } 119 | } 120 | 121 | fun linq88() { 122 | val categories = products.groupBy { it.category } 123 | .map { 124 | val maxPrice = it.value.maxBy { p -> p.unitPrice }?.unitPrice 125 | Pair(it.key, it.value.filter { p -> p.unitPrice == maxPrice }) 126 | } 127 | 128 | categories.forEach { 129 | val (category, mostExpensiveProducts) = it 130 | Log.d("$category: ") 131 | mostExpensiveProducts.forEach { Log.d(it) } 132 | } 133 | } 134 | 135 | fun linq89() { 136 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 137 | 138 | val averageNum = numbers.average() 139 | 140 | Log.d("The average number is $averageNum") 141 | } 142 | 143 | fun linq90() { 144 | val words = arrayOf("cherry", "apple", "blueberry") 145 | 146 | val averageLength = words.map { it.length }.average() 147 | 148 | Log.d("The average word length is $averageLength characters.") 149 | } 150 | 151 | fun linq91() { 152 | val categories = products.groupBy { it.category } 153 | .map { Pair(it.key, it.value.map{it.unitPrice }.average() ) } 154 | 155 | categories.forEach { Log.d("Category: ${it.first}, AveragePrice: ${it.second}") } 156 | } 157 | 158 | fun linq92() { 159 | val doubles = doubleArrayOf(1.7, 2.3, 1.9, 4.1, 2.9) 160 | 161 | val product = doubles.reduce { runningProduct, nextFactor -> runningProduct * nextFactor } 162 | 163 | Log.d("Total product of all numbers: $product") 164 | } 165 | 166 | fun linq93() { 167 | val startBalance = 100 168 | 169 | val attemptedWithdrawals = intArrayOf(20, 10, 40, 50, 10, 70, 30) 170 | 171 | var i = 0 172 | val endBalance = attemptedWithdrawals.reduce { acc, nextWithdrawal -> 173 | val balance = if (i++ == 0 && nextWithdrawal <= acc) startBalance - acc else acc 174 | if (nextWithdrawal <= balance) balance - nextWithdrawal else balance 175 | } 176 | 177 | Log.d("Ending balance: $endBalance") 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/Conversion.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import net.servicestack.client.Log 4 | import java.util.* 5 | 6 | class Conversion { 7 | 8 | fun linq54() { 9 | val doubles = doubleArrayOf(1.7, 2.3, 1.9, 4.1, 2.9) 10 | 11 | val sortedDoubles = doubles.sortedDescending() 12 | 13 | val doublesArray = sortedDoubles.toDoubleArray() 14 | 15 | Log.d("Every other double from highest to lowest:") 16 | var d = 0 17 | while (d < doublesArray.size) { 18 | Log.d(doublesArray[d]) 19 | d += 2 20 | } 21 | } 22 | 23 | fun linq55() { 24 | val words = arrayOf("cherry", "apple", "blueberry") 25 | 26 | val sortedWords = words.sorted() 27 | val wordList = sortedWords.toList() 28 | 29 | Log.d("The sorted word list:") 30 | wordList.forEach { Log.d(it) } 31 | } 32 | 33 | fun linq56() { 34 | val scoreRecords = listOf( 35 | Pair("Alice", 50), 36 | Pair("Bob", 40), 37 | Pair("Cathy", 45) 38 | ) 39 | 40 | val scoreRecordsDict = scoreRecords.toMap() 41 | 42 | Log.d("Bob's score: ${scoreRecordsDict["Bob"]}") 43 | } 44 | 45 | fun linq57() { 46 | val numbers = arrayOf(null, 1.0, "two", 3, "four", 5, "six", 7.0) 47 | 48 | val doubles = numbers.filter { it is Double } 49 | 50 | Log.d("Numbers stored as doubles:") 51 | doubles.forEach { Log.d(it) } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/ElementOperators.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import net.servicestack.client.Log 4 | import servicestack.net.kotlinlinqexamples.support.products 5 | 6 | class ElementOperators { 7 | 8 | fun linq58() { 9 | val product12 = products.filter { it.productId == 12 }.first() 10 | 11 | Log.d(product12) 12 | } 13 | 14 | fun linq59() { 15 | val strings = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") 16 | 17 | val startsWithO = strings.first { it[0] == 'o' } 18 | 19 | Log.d("A string starting with 'o': $startsWithO") 20 | } 21 | 22 | fun linq61() { 23 | val numbers = intArrayOf() 24 | 25 | val firstNumOrDefault = numbers.firstOrNull() ?: 0 26 | 27 | Log.d(firstNumOrDefault) 28 | } 29 | 30 | fun linq62() { 31 | val product789 = products.firstOrNull { it.productId == 789 } 32 | 33 | Log.d("Product 789 exists: ${product789 != null}") 34 | } 35 | 36 | fun linq64() { 37 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 38 | 39 | val fourthLowNum = numbers.filter { it > 5 }[1] 40 | 41 | Log.d("Second number > 5: $fourthLowNum") 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/GenerationOperators.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import net.servicestack.client.Log 4 | 5 | class GenerationOperators { 6 | 7 | fun linq65() { 8 | val numbers = (100..150).map { n -> Pair(n, if (n % 2 == 1) "odd" else "even") } 9 | 10 | numbers.forEach { Log.d("The number ${it.first} is ${it.second}") } 11 | } 12 | 13 | fun linq66() { 14 | val numbers = "7".repeat(10) 15 | 16 | numbers.forEach { Log.d(it) } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/Grouping.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import net.servicestack.client.Log 4 | import net.servicestack.func.Func.groupBy 5 | import servicestack.net.kotlinlinqexamples.support.customers 6 | import servicestack.net.kotlinlinqexamples.support.products 7 | import java.util.* 8 | 9 | class Grouping { 10 | 11 | fun linq40() { 12 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 13 | 14 | val numberGroups = numbers.groupBy { it % 5 } 15 | .map { Pair(it.key, it) } 16 | 17 | numberGroups.forEach { it -> 18 | val (remainder, g) = it 19 | Log.d("Numbers with a remainder of $remainder when divided by 5:") 20 | g.value.forEach { Log.d(it) } 21 | } 22 | } 23 | 24 | fun linq41() { 25 | val words = arrayOf("blueberry", "chimpanzee", "abacus", "banana", "apple", "cheese") 26 | 27 | val wordGroups = words.groupBy { it[0] } 28 | .map { Pair(it.key, it) } 29 | 30 | wordGroups.forEach { 31 | val (firstLetter, g) = it 32 | Log.d("Words that start with the letter '$firstLetter':") 33 | g.value.forEach { Log.d(it) } 34 | } 35 | } 36 | 37 | fun linq42() { 38 | val orderGroups = products.groupBy { it.category } 39 | .map { Pair(it.key, it) } 40 | 41 | orderGroups.forEach { 42 | val (category,g) = it 43 | Log.d("${category}:") 44 | g.value.forEach { Log.d(it) } 45 | } 46 | } 47 | 48 | fun linq43() { 49 | val customerOrderGroups = customers.map { c -> 50 | Pair(c.companyName, 51 | c.orders.groupBy { it.orderDate.year + 1900 } 52 | .map { Pair(it.key, it.value.groupBy { it.orderDate.month + 1 }) }) 53 | } 54 | 55 | customerOrderGroups.forEach { 56 | val (companyName, yearGroups) = it 57 | Log.d("\n# $companyName") 58 | yearGroups.forEach { 59 | val (year,monthGroups) = it 60 | Log.d("${year.toString()}: ") 61 | monthGroups.forEach { Log.d(" $it") } 62 | } 63 | } 64 | } 65 | 66 | fun linq44() { 67 | val anagrams = listOf("from ", " salt", " earn ", " last ", " near ", " form ") 68 | 69 | val orderGroups = groupBy(anagrams, 70 | { w -> w.trim { it <= ' ' } }, 71 | { a, b -> 72 | val aChars = a.toCharArray() 73 | val bChars = b.toCharArray() 74 | Arrays.sort(aChars) 75 | Arrays.sort(bChars) 76 | Arrays.equals(aChars, bChars) 77 | }) 78 | 79 | orderGroups.forEach { g -> 80 | val sb = StringBuilder() 81 | g.forEach { w -> 82 | if (sb.length > 0) 83 | sb.append(", ") 84 | sb.append("'").append(w).append("'") 85 | } 86 | Log.d("[ $sb ]") 87 | } 88 | } 89 | 90 | fun linq45() { 91 | val anagrams = listOf("from ", " salt", " earn ", " last ", " near ", " form ") 92 | 93 | val orderGroups = groupBy(anagrams, 94 | { w -> w.trim { it <= ' ' } }, 95 | { a, b -> 96 | val aChars = a.toCharArray() 97 | val bChars = b.toCharArray() 98 | Arrays.sort(aChars) 99 | Arrays.sort(bChars) 100 | Arrays.equals(aChars, bChars) 101 | }, 102 | { it.toUpperCase() }) 103 | 104 | orderGroups.forEach { g -> 105 | val sb = StringBuilder() 106 | g.forEach { 107 | if (sb.length > 0) 108 | sb.append(", ") 109 | sb.append("'").append(it).append("'") 110 | } 111 | Log.d("[ $sb ]") 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/JoinOperators.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import net.servicestack.client.Log 4 | import net.servicestack.func.Func.join 5 | import net.servicestack.func.Func.joinGroup 6 | import servicestack.net.kotlinlinqexamples.support.products 7 | 8 | class JoinOperators { 9 | 10 | fun linq102() { 11 | val categories = listOf("Beverages", "Condiments", "Vegetables", "Dairy Products", "Seafood") 12 | 13 | val q = join(categories, products) { c, p -> c == p.category } 14 | .map { Pair(it.A, it.B.productName) } 15 | 16 | q.forEach { Log.d("${it.first}: ${it.second}") } 17 | } 18 | 19 | fun linq103() { 20 | val categories = listOf("Beverages", "Condiments", "Vegetables", "Dairy Products", "Seafood") 21 | 22 | val q = joinGroup(categories, products) { c, p -> c == p.category } 23 | .map { Pair(it.key, it.items.map { it.B }) } 24 | 25 | q.forEach { 26 | Log.d("${it.first}:") 27 | it.second.forEach { p -> Log.d(" ${p.productName}") } 28 | } 29 | } 30 | 31 | fun linq104() { 32 | val categories = listOf("Beverages", "Condiments", "Vegetables", "Dairy Products", "Seafood") 33 | 34 | val q = joinGroup(categories, products) { c, p -> c == p.category } 35 | .flatMap { j -> j.items.map { it.B }.map { Pair(j.key, it.productName) } } 36 | 37 | q.forEach { Log.d("${it.second}: ${it.first}") } 38 | } 39 | 40 | fun linq105() { 41 | val categories = listOf("Beverages", "Condiments", "Vegetables", "Dairy Products", "Seafood") 42 | 43 | val q = categories.flatMap { c -> 44 | val catProducts = products.filter { c == it.category } 45 | if (catProducts.isEmpty()) 46 | listOf(Pair(c, "(No products)")) 47 | else 48 | catProducts.map { Pair(c, it.productName) } 49 | } 50 | 51 | q.forEach { Log.d("${it.second}: ${it.first}") } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import android.app.Activity 4 | import android.os.Bundle 5 | import android.view.Menu 6 | import android.view.MenuItem 7 | import android.view.View 8 | import android.widget.ScrollView 9 | import android.widget.TextView 10 | import net.servicestack.client.Log 11 | import net.servicestack.client.LogProvider 12 | import net.servicestack.client.LogType 13 | import servicestack.net.kotlinlinqexamples.support.init 14 | import java.lang.reflect.InvocationTargetException 15 | 16 | class MainActivity : Activity() { 17 | 18 | inner class StringBuilderLogProvider(internal var sb: StringBuilder) : LogProvider(null, true) { 19 | 20 | override fun println(type: LogType, message: Any?) { 21 | sb.append("\n").append(message!!.toString()) 22 | } 23 | } 24 | 25 | internal var sb: StringBuilder = StringBuilder() 26 | override fun onCreate(savedInstanceState: Bundle?) { 27 | super.onCreate(savedInstanceState) 28 | setContentView(R.layout.activity_main) 29 | 30 | val bar = actionBar 31 | bar.setDisplayShowHomeEnabled(true) 32 | bar.setLogo(R.drawable.ic_action_android) 33 | bar.setDisplayUseLogoEnabled(true) 34 | 35 | sb = StringBuilder() 36 | Log.Instance = StringBuilderLogProvider(sb) 37 | init(resources) 38 | 39 | Log.i("101 Kotlin LINQ Examples") 40 | Log.i("========================\n") 41 | Run(Restrictions()) 42 | Run(Projections()) 43 | Run(Partitioning()) 44 | Run(Ordering()) 45 | Run(Grouping()) 46 | Run(SetOperators()) 47 | Run(Conversion()) 48 | Run(ElementOperators()) 49 | Run(GenerationOperators()) 50 | Run(Quantifiers()) 51 | Run(AggregateOperators()) 52 | Run(MiscOperators()) 53 | Run(QueryExecution()) 54 | Run(JoinOperators()) 55 | } 56 | 57 | internal fun Run(linqExamples: Any) { 58 | val cls = linqExamples.javaClass 59 | val methods = cls.methods 60 | for (method in methods) { 61 | if (method.declaringClass != cls || method.parameterTypes.size != 0) 62 | continue 63 | 64 | Log.i("\n# " + method.name.toUpperCase()) 65 | try { 66 | method.invoke(linqExamples) 67 | } catch (e: IllegalAccessException) { 68 | Log.e(e.cause.toString()) 69 | e.printStackTrace() 70 | } catch (e: InvocationTargetException) { 71 | Log.e(e.cause.toString()) 72 | e.printStackTrace() 73 | } 74 | 75 | } 76 | 77 | val txtMain = findViewById(R.id.txtMain) as TextView 78 | txtMain.text = sb.toString() 79 | 80 | val scrollView = findViewById(R.id.scrollView) as ScrollView 81 | scrollView.post { scrollView.fullScroll(View.FOCUS_DOWN) } 82 | } 83 | 84 | override fun onCreateOptionsMenu(menu: Menu): Boolean { 85 | // Inflate the menu; this adds items to the action bar if it is present. 86 | menuInflater.inflate(R.menu.menu_main, menu) 87 | return true 88 | } 89 | 90 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 91 | // Handle action bar item clicks here. The action bar will 92 | // automatically handle clicks on the Home/Up button, so long 93 | // as you specify a parent activity in AndroidManifest.xml. 94 | val id = item.itemId 95 | 96 | //noinspection SimplifiableIfStatement 97 | if (id == R.id.action_settings) { 98 | return true 99 | } 100 | 101 | return super.onOptionsItemSelected(item) 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/MiscOperators.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import net.servicestack.client.Log 4 | import servicestack.net.kotlinlinqexamples.support.customers 5 | import servicestack.net.kotlinlinqexamples.support.products 6 | import java.util.* 7 | 8 | class MiscOperators { 9 | 10 | fun linq94() { 11 | val numbersA = intArrayOf(0, 2, 4, 5, 6, 8, 9) 12 | val numbersB = intArrayOf(1, 3, 5, 7, 8) 13 | 14 | val allNumbers = numbersA + numbersB 15 | 16 | Log.d("All numbers from both arrays:") 17 | allNumbers.forEach { Log.d(it) } 18 | } 19 | 20 | fun linq95() { 21 | val customerNames = customers.map { it.companyName } 22 | 23 | val productNames = products.map { it.productName } 24 | 25 | val allNames = customerNames + productNames 26 | 27 | Log.d("Customer and product names:") 28 | allNames.forEach { Log.d(it) } 29 | } 30 | 31 | fun linq96() { 32 | val wordsA = arrayOf("cherry", "apple", "blueberry") 33 | val wordsB = arrayOf("cherry", "apple", "blueberry") 34 | 35 | val match = Arrays.equals(wordsA, wordsB) 36 | 37 | Log.d("The sequences match: $match") 38 | } 39 | 40 | fun linq97() { 41 | val wordsA = arrayOf("cherry", "apple", "blueberry") 42 | val wordsB = arrayOf("cherry", "blueberry", "cherry") 43 | 44 | val match = Arrays.equals(wordsA, wordsB) 45 | 46 | Log.d("The sequences match: $match") 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/Ordering.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import net.servicestack.client.Log 4 | import net.servicestack.func.Func.orderByAll 5 | import servicestack.net.kotlinlinqexamples.support.Product 6 | import servicestack.net.kotlinlinqexamples.support.products 7 | import java.util.* 8 | 9 | class Ordering { 10 | 11 | fun linq28() { 12 | val words = arrayOf("cherry", "apple", "blueberry") 13 | 14 | val sortedWords = words.sorted() 15 | 16 | Log.d("The sorted list of words:") 17 | sortedWords.forEach { Log.d(it) } 18 | } 19 | 20 | fun linq29() { 21 | val words = arrayOf("cherry", "apple", "blueberry") 22 | 23 | val sortedWords = words.sortedBy { s -> s.length } 24 | 25 | Log.d("The sorted list of words (by length):") 26 | sortedWords.forEach { Log.d(it) } 27 | } 28 | 29 | fun linq30() { 30 | val sortedProducts = products.sortedBy { it.productName } 31 | 32 | sortedProducts.forEach { Log.d(it) } 33 | } 34 | 35 | fun linq31() { 36 | val words = arrayOf("aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry") 37 | 38 | val sortedWords = words.sortedWith(String.CASE_INSENSITIVE_ORDER) 39 | 40 | sortedWords.forEach { Log.d(it) } 41 | } 42 | 43 | fun linq32() { 44 | val doubles = doubleArrayOf(1.7, 2.3, 1.9, 4.1, 2.9) 45 | 46 | val sortedDoubles = doubles.sortedDescending() 47 | 48 | Log.d("The doubles from highest to lowest:") 49 | sortedDoubles.forEach { Log.d(it) } 50 | } 51 | 52 | fun linq33() { 53 | val sortedProducts = products.sortedByDescending { it.unitsInStock } 54 | 55 | sortedProducts.forEach { Log.d(it) } 56 | } 57 | 58 | fun linq34() { 59 | val words = arrayOf("aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry") 60 | 61 | val sortedWords = words.sortedWith(String.CASE_INSENSITIVE_ORDER).reversed() 62 | 63 | sortedWords.forEach { Log.d(it) } 64 | } 65 | 66 | fun linq35() { 67 | val digits = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") 68 | 69 | val sortedDigits = digits.sorted().sortedBy { it.length } 70 | 71 | Log.d("Sorted digits:") 72 | sortedDigits.forEach { Log.d(it) } 73 | } 74 | 75 | fun linq36() { 76 | val words = arrayOf("aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry") 77 | 78 | val sortedWords = words.sortedWith(String.CASE_INSENSITIVE_ORDER).sortedBy { it.length } 79 | 80 | sortedWords.forEach { Log.d(it) } 81 | } 82 | 83 | fun linq37() { 84 | val sortedProducts = orderByAll(products, 85 | Comparator { a, b -> a.category.compareTo(b.category) }, 86 | Comparator { a, b -> b.unitPrice.compareTo(a.unitPrice) }) 87 | 88 | sortedProducts.forEach { Log.d(it) } 89 | } 90 | 91 | fun linq38() { 92 | val words = arrayOf("aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry") 93 | 94 | val sortedWords = orderByAll(words, 95 | Comparator { a, b -> Integer.compare(a.length, b.length) }, 96 | Comparator { a, b -> String.CASE_INSENSITIVE_ORDER.compare(b, a) }) 97 | 98 | sortedWords.forEach { Log.d(it) } 99 | } 100 | 101 | fun linq39() { 102 | val digits = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") 103 | 104 | val reversedIDigits = digits.filter { it[1] == 'i' }.reversed() 105 | 106 | Log.d("A backwards list of the digits with a second character of 'i':") 107 | reversedIDigits.forEach { Log.d(it) } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/Partitioning.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import net.servicestack.client.Log 4 | import servicestack.net.kotlinlinqexamples.support.customers 5 | 6 | class Partitioning { 7 | 8 | fun linq20() { 9 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 10 | 11 | val first3Numbers = numbers.take(3) 12 | 13 | Log.d("First 3 numbers:") 14 | first3Numbers.forEach { Log.d(it) } 15 | } 16 | 17 | fun linq21() { 18 | val first3WAOrders = customers 19 | .filter { it.region == "WA" } 20 | .flatMap { c -> 21 | c.orders.map { o -> Triple(c.customerId, o.orderId, o.orderDate) } 22 | } 23 | .take(3) 24 | 25 | Log.d("First 3 orders in WA:") 26 | first3WAOrders.forEach { Log.d(it) } 27 | } 28 | 29 | fun linq22() { 30 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 31 | 32 | val allButFirst4Numbers = numbers.drop(4) 33 | 34 | Log.d("All but first 4 numbers:") 35 | allButFirst4Numbers.forEach { Log.d(it) } 36 | } 37 | 38 | fun linq23() { 39 | val waOrders = customers 40 | .filter { it.region == "WA" } 41 | .flatMap { c -> 42 | c.orders.map { o -> Triple(c.customerId, o.orderId, o.orderDate) } 43 | } 44 | 45 | val allButFirst2Orders = waOrders.drop(2) 46 | 47 | Log.d("All but first 2 orders in WA:") 48 | allButFirst2Orders.forEach { Log.d(it) } 49 | } 50 | 51 | fun linq24() { 52 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 53 | 54 | val firstNumbersLessThan6 = numbers.takeWhile { it < 6 } 55 | 56 | Log.d("First numbers less than 6:") 57 | firstNumbersLessThan6.forEach { Log.d(it) } 58 | } 59 | 60 | fun linq25() { 61 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 62 | 63 | var index = 0 64 | val firstSmallNumbers = numbers.takeWhile { it >= index++ } 65 | 66 | Log.d("First numbers not less than their position:") 67 | firstSmallNumbers.forEach { Log.d(it) } 68 | } 69 | 70 | fun linq26() { 71 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 72 | 73 | val allButFirst3Numbers = numbers.dropWhile { it % 3 != 0 } 74 | 75 | Log.d("All elements starting from first element divisible by 3:") 76 | allButFirst3Numbers.forEach { Log.d(it) } 77 | } 78 | 79 | fun linq27() { 80 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 81 | 82 | var index = 0 83 | val laterNumbers = numbers.dropWhile { it >= index++ } 84 | 85 | Log.d("All elements starting from first element less than its position:") 86 | laterNumbers.forEach { Log.d(it) } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/Projections.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import net.servicestack.client.Log 4 | import servicestack.net.kotlinlinqexamples.support.customers 5 | import servicestack.net.kotlinlinqexamples.support.products 6 | import java.util.* 7 | 8 | class Projections { 9 | 10 | fun linq06() { 11 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 12 | 13 | val numsPlusOne = numbers.map { it + 1 } 14 | 15 | Log.d("Numbers + 1:") 16 | numsPlusOne.forEach { Log.d(it) } 17 | } 18 | 19 | fun linq07() { 20 | val productNames = products.map { it.productName } 21 | 22 | Log.d("Product Names:") 23 | productNames.forEach { Log.d(it) } 24 | } 25 | 26 | fun linq08() { 27 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 28 | val strings = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") 29 | 30 | val textNums = numbers.map { strings[it] } 31 | 32 | Log.d("Number strings:") 33 | textNums.forEach { Log.d(it) } 34 | } 35 | 36 | fun linq09() { 37 | val words = arrayOf("aPPLE", "BlUeBeRrY", "cHeRry") 38 | 39 | val upperLowerWords = words.map { w -> Pair(w.toUpperCase(), w.toLowerCase()) } 40 | 41 | upperLowerWords.forEach { Log.d("Uppercase: ${it.first}, Lowercase: ${it.second}") } 42 | } 43 | 44 | fun linq10() { 45 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 46 | val strings = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") 47 | 48 | val digitOddEvens = numbers.map { Pair(strings[it], it % 2 == 0) } 49 | 50 | digitOddEvens.forEach { 51 | val (d,isEven) = it 52 | Log.d("The digit $d is ${if (isEven) "even" else "odd"}.") 53 | } 54 | } 55 | 56 | fun linq11() { 57 | val productInfos = products.map { p -> Triple(p.productName, p.category, p.unitPrice) } 58 | 59 | Log.d("Product Info:") 60 | productInfos.forEach { 61 | val (name,category,cost) = it 62 | Log.d("$name is in the category $category and costs $cost per unit.") 63 | } 64 | } 65 | 66 | fun linq12() { 67 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 68 | 69 | val numsInPlace = numbers.mapIndexed { index, n -> Pair(n, n == index) } 70 | 71 | Log.d("Number: In-place?") 72 | numsInPlace.forEach { Log.d("${it.first.toString()}: ${it.second}") } 73 | } 74 | 75 | fun linq13() { 76 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 77 | val digits = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") 78 | 79 | val lowNums = numbers.filter { it < 5 }.map { digits[it] } 80 | 81 | Log.d("Numbers < 5:") 82 | lowNums.forEach { Log.d(it) } 83 | } 84 | 85 | fun linq14() { 86 | val numbersA = intArrayOf(0, 2, 4, 5, 6, 8, 9) 87 | val numbersB = intArrayOf(1, 3, 5, 7, 8) 88 | 89 | val pairs = numbersA.flatMap { a -> 90 | numbersB.filter { b -> a < b } 91 | .map { Pair(a, it) } 92 | } 93 | 94 | Log.d("Pairs where a < b:") 95 | pairs.forEach { Log.d("${it.first.toString()} is less than ${it.second}") } 96 | } 97 | 98 | fun linq15() { 99 | val orders = customers.flatMap { c -> 100 | c.orders.filter { it.total < 500 } 101 | .map { o -> Triple(c.customerId, o.orderId, o.total) } 102 | } 103 | 104 | orders.forEach { Log.d(it) } 105 | } 106 | 107 | fun linq16() { 108 | val date = Date(98, 0, 1) //= 1998-01-01 109 | val orders = customers.flatMap { c -> 110 | c.orders.filter { it.orderDate >= date } 111 | .map { o -> Triple(c.customerId, o.orderId, o.orderDate) } 112 | } 113 | 114 | orders.forEach { Log.d(it) } 115 | } 116 | 117 | fun linq17() { 118 | val orders = customers.flatMap { c -> 119 | c.orders.filter { it.total >= 2000 } 120 | .map { o -> Triple(c.customerId, o.orderId, o.total) } 121 | } 122 | 123 | orders.forEach { Log.d(it) } 124 | } 125 | 126 | fun linq18() { 127 | val cutoffDate = Date(97, 0, 1) //1997-01-01 128 | 129 | val orders = customers 130 | .filter { it.region == "WA" }.flatMap { c -> 131 | c.orders.filter { it.orderDate > cutoffDate } 132 | .map { o -> Pair(c.customerId, o.orderId) } 133 | } 134 | 135 | orders.forEach { Log.d(it) } 136 | } 137 | 138 | fun linq19() { 139 | var custIndex = 0 140 | val customerOrders = customers.flatMap { c -> 141 | c.orders.mapIndexed { index, o -> "Customer #$index has an order with OrderID ${o.orderId}" } 142 | } 143 | 144 | customerOrders.forEach { Log.d(it) } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/Quantifiers.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import net.servicestack.client.Log 4 | import servicestack.net.kotlinlinqexamples.support.products 5 | 6 | class Quantifiers { 7 | 8 | fun linq67() { 9 | val words = arrayOf("believe", "relief", "receipt", "field") 10 | 11 | val iAfterE = words.any { it.contains("ei") } 12 | 13 | Log.d("There is a word that contains in the list that contains 'ei': $iAfterE") 14 | } 15 | 16 | fun linq69() { 17 | val productGroups = products 18 | .groupBy { it.category } 19 | .filter { it.value.any { it.unitsInStock == 0 } } 20 | .map { Pair(it.key, it) } 21 | 22 | productGroups.forEach { Log.d(it.second) } 23 | } 24 | 25 | fun linq70() { 26 | val numbers = intArrayOf(1, 11, 3, 19, 41, 65, 19) 27 | 28 | val onlyOdd = numbers.all { it % 2 == 1 } 29 | 30 | Log.d("The list contains only odd numbers: $onlyOdd") 31 | } 32 | 33 | fun linq72() { 34 | val productGroups = products 35 | .groupBy { it.category } 36 | .filter { it.value.all { it.unitsInStock > 0 } } 37 | .map { Pair(it.key, it) } 38 | 39 | productGroups.forEach { Log.d(it.second) } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/QueryExecution.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import net.servicestack.client.Log 4 | 5 | class QueryExecution { 6 | 7 | fun linq099() { 8 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 9 | 10 | var i = 0 11 | val q = numbers.map { { ++i } } 12 | 13 | for (f in q) { 14 | val v = f() 15 | Log.d("v = $v, i = $i") 16 | } 17 | } 18 | 19 | fun linq100() { 20 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 21 | 22 | var i = 0 23 | val q = numbers.map { ++i } 24 | 25 | q.forEach { v -> Log.d("v = $v, i = $i") } 26 | } 27 | 28 | fun linq101() { 29 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 30 | 31 | val lowNumbers = { numbers.filter { n -> n <= 3 } } 32 | 33 | Log.d("First run numbers <= 3:") 34 | lowNumbers().forEach { Log.d(it) } 35 | 36 | for (i in 0..9) { 37 | numbers[i] = -numbers[i] 38 | } 39 | 40 | Log.d("Second run numbers <= 3:") 41 | lowNumbers().forEach { Log.d(it) } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/Restrictions.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import net.servicestack.client.Log 4 | import servicestack.net.kotlinlinqexamples.support.customers 5 | import servicestack.net.kotlinlinqexamples.support.dateFmt 6 | import servicestack.net.kotlinlinqexamples.support.products 7 | 8 | class Restrictions { 9 | 10 | fun linq1() { 11 | val numbers = intArrayOf(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) 12 | 13 | val lowNums = numbers.filter { it < 5 } 14 | 15 | Log.d("Numbers < 5:") 16 | lowNums.forEach { Log.d(it) } 17 | } 18 | 19 | fun linq2() { 20 | val soldOutProducts = products.filter { it.unitsInStock == 0 } 21 | 22 | Log.d("Sold out products:") 23 | soldOutProducts.forEach { Log.d("${it.productName} is sold out!") } 24 | } 25 | 26 | fun linq3() { 27 | val expensiveInStockProducts = products.filter { it.unitsInStock > 0 && it.unitPrice > 3.00 } 28 | 29 | Log.d("In-stock products that cost more than 3.00:") 30 | expensiveInStockProducts.forEach { Log.d("${it.productName} is in stock and costs more than 3.00.") } 31 | } 32 | 33 | fun linq4() { 34 | val waCustomers = customers.filter { "WA" == it.region } 35 | 36 | Log.d("Customers from Washington and their orders:") 37 | waCustomers.forEach { c -> 38 | Log.d("Customer ${c.customerId} ${c.companyName}") 39 | c.orders.forEach { Log.d(" Order ${it.orderId}: ${dateFmt(it.orderDate)}") } 40 | } 41 | } 42 | 43 | fun linq5() { 44 | val digits = arrayOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") 45 | 46 | val shortDigits = digits.filterIndexed { i, it -> it.length < i } 47 | 48 | Log.d("Short digits:") 49 | shortDigits.forEach { Log.d("The word $it is shorter than its value.") } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/SetOperators.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import net.servicestack.client.Log 4 | import servicestack.net.kotlinlinqexamples.support.customers 5 | import servicestack.net.kotlinlinqexamples.support.products 6 | 7 | class SetOperators { 8 | 9 | fun linq46() { 10 | val factorsOf300 = intArrayOf(2, 2, 3, 5, 5) 11 | 12 | val uniqueFactors = factorsOf300.distinct() 13 | 14 | Log.d("Prime factors of 300:") 15 | uniqueFactors.forEach { Log.d(it) } 16 | } 17 | 18 | fun linq47() { 19 | val categoryNames = products.map { it.category}.distinct() 20 | 21 | Log.d("Category names:") 22 | categoryNames.forEach { Log.d(it) } 23 | } 24 | 25 | fun linq48() { 26 | val numbersA = listOf(0, 2, 4, 5, 6, 8, 9) 27 | val numbersB = listOf(1, 3, 5, 7, 8) 28 | 29 | val uniqueNumbers = numbersA.union(numbersB) 30 | 31 | Log.d("Unique numbers from both arrays:") 32 | uniqueNumbers.forEach { Log.d(it) } 33 | } 34 | 35 | fun linq49() { 36 | val productFirstChars = products.map { it.productName[0] } 37 | 38 | val customerFirstChars = customers.map { it.companyName[0] } 39 | 40 | val uniqueFirstChars = productFirstChars.union(customerFirstChars) 41 | 42 | Log.d("Unique first letters from Product names and Customer names:") 43 | uniqueFirstChars.forEach { Log.d(it) } 44 | } 45 | 46 | fun linq50() { 47 | val numbersA = listOf(0, 2, 4, 5, 6, 8, 9) 48 | val numbersB = listOf(1, 3, 5, 7, 8) 49 | 50 | val commonNumbers = numbersA.intersect(numbersB) 51 | 52 | Log.d("Common numbers shared by both arrays:") 53 | commonNumbers.forEach { Log.d(it) } 54 | } 55 | 56 | fun linq51() { 57 | val productFirstChars = products.map { it.productName[0] } 58 | 59 | val customerFirstChars = customers.map { it.companyName[0] } 60 | 61 | val commonFirstChars = productFirstChars.intersect(customerFirstChars) 62 | 63 | Log.d("Common first letters from Product names and Customer names:") 64 | commonFirstChars.forEach { Log.d(it) } 65 | } 66 | 67 | fun linq52() { 68 | val numbersA = listOf(0, 2, 4, 5, 6, 8, 9) 69 | val numbersB = listOf(1, 3, 5, 7, 8) 70 | 71 | val aOnlyNumbers = numbersA.difference(numbersB) 72 | 73 | Log.d("Numbers in first array but not second array:") 74 | aOnlyNumbers.forEach { Log.d(it) } 75 | } 76 | 77 | fun linq53() { 78 | val productFirstChars = products.map { it.productName[0] } 79 | 80 | val customerFirstChars = customers.map { it.companyName[0] } 81 | 82 | val productOnlyFirstChars = productFirstChars.difference(customerFirstChars) 83 | 84 | Log.d("First letters from Product names, but not from Customer names:") 85 | productOnlyFirstChars.forEach { Log.d(it) } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/extensions.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples 2 | 3 | import java.util.* 4 | 5 | fun IntArray.difference(other:IntArray): List { 6 | var to = ArrayList() 7 | for (x in this) { 8 | if (!other.contains(x) && !to.contains(x)) { 9 | to.add(x) 10 | } 11 | } 12 | return to 13 | } 14 | 15 | fun List.difference(other:List): List { 16 | var to = ArrayList() 17 | for (x in this) { 18 | if (!other.contains(x) && !to.contains(x)) { 19 | to.add(x) 20 | } 21 | } 22 | return to 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/support/Customer.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples.support 2 | 3 | import java.util.ArrayList 4 | 5 | class Customer { 6 | var customerId: String? = null 7 | var companyName: String = "" 8 | var address: String? = null 9 | var city: String? = null 10 | var region: String? = null 11 | var postalCode: String? = null 12 | var country: String? = null 13 | var phone: String? = null 14 | var fax: String? = null 15 | var orders: List 16 | 17 | init { 18 | orders = ArrayList() 19 | } 20 | 21 | override fun toString(): String { 22 | return "Customer{" + "customerId='" + customerId + '\'' + ", companyName='" + companyName + '\'' + ", orders='" + orders.size + '\'' + '}' 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/support/Data.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples.support 2 | 3 | import android.content.res.Resources 4 | import com.google.gson.GsonBuilder 5 | import com.google.gson.JsonDeserializer 6 | import net.servicestack.func.Func.toList 7 | import servicestack.net.kotlinlinqexamples.R 8 | import java.io.BufferedReader 9 | import java.io.InputStreamReader 10 | import java.text.ParseException 11 | import java.text.SimpleDateFormat 12 | import java.util.* 13 | 14 | val products: List by lazy { 15 | listOf( 16 | Product(1, "Chai", "Beverages", 18.000, 39), 17 | Product(2, "Chang", "Beverages", 19.000, 17), 18 | Product(3, "Aniseed Syrup", "Condiments", 10.000, 13), 19 | Product(4, "Chef Anton's Cajun Seasoning", "Condiments", 22.000, 53), 20 | Product(5, "Chef Anton's Gumbo Mix", "Condiments", 21.350, 0), 21 | Product(6, "Grandma's Boysenberry Spread", "Condiments", 25.000, 120), 22 | Product(7, "Uncle Bob's Organic Dried Pears", "Produce", 30.000, 15), 23 | Product(8, "Northwoods Cranberry Sauce", "Condiments", 40.000, 6), 24 | Product(9, "Mishi Kobe Niku", "Meat/Poultry", 97.000, 29), 25 | Product(10, "Ikura", "Seafood", 31.000, 31), 26 | Product(11, "Queso Cabrales", "Dairy Products", 21.000, 22), 27 | Product(12, "Queso Manchego La Pastora", "Dairy Products", 38.000, 86), 28 | Product(13, "Konbu", "Seafood", 6.000, 24), 29 | Product(14, "Tofu", "Produce", 23.250, 35), 30 | Product(15, "Genen Shouyu", "Condiments", 15.500, 39), 31 | Product(16, "Pavlova", "Confections", 17.450, 29), 32 | Product(17, "Alice Mutton", "Meat/Poultry", 39.000, 0), 33 | Product(18, "Carnarvon Tigers", "Seafood", 62.500, 42), 34 | Product(19, "Teatime Chocolate Biscuits", "Confections", 9.200, 25), 35 | Product(20, "Sir Rodney's Marmalade", "Confections", 81.000, 40), 36 | Product(21, "Sir Rodney's Scones", "Confections", 10.000, 3), 37 | Product(22, "Gustaf's Kn\u00e4ckebr\u00f6d", "Grains/Cereals", 21.000, 104), 38 | Product(23, "Tunnbr\u00f6d", "Grains/Cereals", 9.000, 61), 39 | Product(24, "Guaran\u00e1 Fant\u00e1stica", "Beverages", 4.500, 20), 40 | Product(25, "NuNuCa Nu\u00df-Nougat-Creme", "Confections", 14.000, 76), 41 | Product(26, "Gumb\u00e4r Gummib\u00e4rchen", "Confections", 31.230, 15), 42 | Product(27, "Schoggi Schokolade", "Confections", 43.900, 49), 43 | Product(28, "R\u00f6ssle Sauerkraut", "Produce", 45.600, 26), 44 | Product(29, "Th\u00fcringer Rostbratwurst", "Meat/Poultry", 123.790, 0), 45 | Product(30, "Nord-Ost Matjeshering", "Seafood", 25.890, 10), 46 | Product(31, "Gorgonzola Telino", "Dairy Products", 12.500, 0), 47 | Product(32, "Mascarpone Fabioli", "Dairy Products", 32.000, 9), 48 | Product(33, "Geitost", "Dairy Products", 2.500, 112), 49 | Product(34, "Sasquatch Ale", "Beverages", 14.000, 111), 50 | Product(35, "Steeleye Stout", "Beverages", 18.000, 20), 51 | Product(36, "Inlagd Sill", "Seafood", 19.000, 112), 52 | Product(37, "Gravad lax", "Seafood", 26.000, 11), 53 | Product(38, "C\u00f4te de Blaye", "Beverages", 263.500, 17), 54 | Product(39, "Chartreuse verte", "Beverages", 18.000, 69), 55 | Product(40, "Boston Crab Meat", "Seafood", 18.400, 123), 56 | Product(41, "Jack's New England Clam Chowder", "Seafood", 9.650, 85), 57 | Product(42, "Singaporean Hokkien Fried Mee", "Grains/Cereals", 14.000, 26), 58 | Product(43, "Ipoh Coffee", "Beverages", 46.000, 17), 59 | Product(44, "Gula Malacca", "Condiments", 19.450, 27), 60 | Product(45, "Rogede sild", "Seafood", 9.500, 5), 61 | Product(46, "Spegesild", "Seafood", 12.000, 95), 62 | Product(47, "Zaanse koeken", "Confections", 9.500, 36), 63 | Product(48, "Chocolade", "Confections", 12.750, 15), 64 | Product(49, "Maxilaku", "Confections", 20.000, 10), 65 | Product(50, "Valkoinen suklaa", "Confections", 16.250, 65), 66 | Product(51, "Manjimup Dried Apples", "Produce", 53.000, 20), 67 | Product(52, "Filo Mix", "Grains/Cereals", 7.000, 38), 68 | Product(53, "Perth Pasties", "Meat/Poultry", 32.800, 0), 69 | Product(54, "Tourti\u00e8re", "Meat/Poultry", 7.450, 21), 70 | Product(55, "P\u00e2t\u00e9 chinois", "Meat/Poultry", 24.000, 115), 71 | Product(56, "Gnocchi di nonna Alice", "Grains/Cereals", 38.000, 21), 72 | Product(57, "Ravioli Angelo", "Grains/Cereals", 19.500, 36), 73 | Product(58, "Escargots de Bourgogne", "Seafood", 13.250, 62), 74 | Product(59, "Raclette Courdavault", "Dairy Products", 55.000, 79), 75 | Product(60, "Camembert Pierrot", "Dairy Products", 34.000, 19), 76 | Product(61, "Sirop d'\u00e9rable", "Condiments", 28.500, 113), 77 | Product(62, "Tarte au sucre", "Confections", 49.300, 17), 78 | Product(63, "Vegie-spread", "Condiments", 43.900, 24), 79 | Product(64, "Wimmers gute Semmelkn\u00f6del", "Grains/Cereals", 33.250, 22), 80 | Product(65, "Louisiana Fiery Hot Pepper Sauce", "Condiments", 21.050, 76), 81 | Product(66, "Louisiana Hot Spiced Okra", "Condiments", 17.000, 4), 82 | Product(67, "Laughing Lumberjack Lager", "Beverages", 14.000, 52), 83 | Product(68, "Scottish Longbreads", "Confections", 12.500, 6), 84 | Product(69, "Gudbrandsdalsost", "Dairy Products", 36.000, 26), 85 | Product(70, "Outback Lager", "Beverages", 15.000, 15), 86 | Product(71, "Flotemysost", "Dairy Products", 21.500, 26), 87 | Product(72, "Mozzarella di Giovanni", "Dairy Products", 34.800, 14), 88 | Product(73, "R\u00f6d Kaviar", "Seafood", 15.000, 101), 89 | Product(74, "Longlife Tofu", "Produce", 10.000, 4), 90 | Product(75, "Rh\u00f6nbr\u00e4u Klosterbier", "Beverages", 7.750, 125), 91 | Product(76, "Lakkalik\u00f6\u00f6ri", "Beverages", 18.000, 57), 92 | Product(77, "Original Frankfurter gr\u00fcne So\u00dfe", "Condiments", 13.000, 32)) 93 | } 94 | 95 | val dateDeserializer: JsonDeserializer 96 | get() { 97 | val iso8601Formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss") 98 | 99 | return JsonDeserializer { json, typeOfT, context -> 100 | try { 101 | return@JsonDeserializer if (json == null) null else iso8601Formatter.parse(json.asString) 102 | } catch (e: ParseException) { 103 | throw RuntimeException(e) 104 | } 105 | } 106 | } 107 | 108 | internal var _customers: ArrayList = ArrayList() 109 | fun init(res: Resources) { 110 | try { 111 | val stream = res.openRawResource(R.raw.customers) 112 | val reader = BufferedReader(InputStreamReader(stream, "UTF-8")) 113 | 114 | val gson = GsonBuilder().registerTypeAdapter(Date::class.java, dateDeserializer).create() 115 | 116 | val c = gson.fromJson(reader, Array::class.java) 117 | _customers = toList(*c) 118 | 119 | reader.close() 120 | } catch (e: Exception) { 121 | throw RuntimeException(e) 122 | } 123 | } 124 | 125 | val customers: List by lazy { 126 | _customers 127 | } 128 | 129 | internal var dateFormat = SimpleDateFormat("yyyy/MM/dd") 130 | 131 | fun dateFmt(date: Date?): String { 132 | if (date == null) 133 | return "" 134 | 135 | return dateFormat.format(date) 136 | } 137 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/support/Order.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples.support 2 | 3 | import java.util.Date 4 | 5 | class Order(var orderId: Int?, var orderDate: Date, var total: Double) { 6 | 7 | override fun toString(): String { 8 | return "(Order id=$orderId, total=$total)" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/app/src/main/java/servicestack/net/kotlinlinqexamples/support/Product.kt: -------------------------------------------------------------------------------- 1 | package servicestack.net.kotlinlinqexamples.support 2 | 3 | class Product(var productId: Int, var productName: String, var category: String, var unitPrice: Double, var unitsInStock: Int) { 4 | 5 | override fun toString(): String { 6 | return "(Product id=$productId, name=$productName, cat=$category, price=$unitPrice, inStock=$unitsInStock)" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/app/src/main/res/drawable-hdpi/ic_action_android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mythz/kotlin-linq-examples/3b2f2c99a83173a8baf662fa3bd2114eb8f00572/src/app/src/main/res/drawable-hdpi/ic_action_android.png -------------------------------------------------------------------------------- /src/app/src/main/res/drawable-mdpi/ic_action_android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mythz/kotlin-linq-examples/3b2f2c99a83173a8baf662fa3bd2114eb8f00572/src/app/src/main/res/drawable-mdpi/ic_action_android.png -------------------------------------------------------------------------------- /src/app/src/main/res/drawable-xhdpi/ic_action_android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mythz/kotlin-linq-examples/3b2f2c99a83173a8baf662fa3bd2114eb8f00572/src/app/src/main/res/drawable-xhdpi/ic_action_android.png -------------------------------------------------------------------------------- /src/app/src/main/res/drawable-xxhdpi/ic_action_android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mythz/kotlin-linq-examples/3b2f2c99a83173a8baf662fa3bd2114eb8f00572/src/app/src/main/res/drawable-xxhdpi/ic_action_android.png -------------------------------------------------------------------------------- /src/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 14 | 15 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/app/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /src/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mythz/kotlin-linq-examples/3b2f2c99a83173a8baf662fa3bd2114eb8f00572/src/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mythz/kotlin-linq-examples/3b2f2c99a83173a8baf662fa3bd2114eb8f00572/src/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mythz/kotlin-linq-examples/3b2f2c99a83173a8baf662fa3bd2114eb8f00572/src/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mythz/kotlin-linq-examples/3b2f2c99a83173a8baf662fa3bd2114eb8f00572/src/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | -------------------------------------------------------------------------------- /src/app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /src/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #8BC34A 4 | #689F38 5 | #DCEDC8 6 | #448AFF 7 | #FFFFFF 8 | #727272 9 | #212121 10 | #B6B6B6 11 | 12 | -------------------------------------------------------------------------------- /src/app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /src/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Kotlin LINQ Examples 3 | 4 | Hello world! 5 | Settings 6 | 7 | -------------------------------------------------------------------------------- /src/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:1.5.0' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true -------------------------------------------------------------------------------- /src/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mythz/kotlin-linq-examples/3b2f2c99a83173a8baf662fa3bd2114eb8f00572/src/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Dec 11 10:49:06 PST 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip 7 | -------------------------------------------------------------------------------- /src/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /src/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /src/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /src/src.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | --------------------------------------------------------------------------------