sorted* moved to Iterable
in-place List sort v0.8.15-SNAPSHOT
This commit is contained in:
		
							parent
							
								
									a5e51a3f90
								
							
						
					
					
						commit
						0ec0ed96ee
					
				@ -6,6 +6,12 @@ Is a [Iterable] with known `size`, a finite [Iterable]:
 | 
				
			|||||||
        val size
 | 
					        val size
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					| name                   | description                                          |
 | 
				
			||||||
 | 
					|------------------------|------------------------------------------------------|
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(1)
 | 
				
			||||||
 | 
					: `comparator(a,b)` should return -1 if `a < b`, +1 if `a > b` or zero.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
See [List], [Set] and [Iterable]
 | 
					See [List], [Set] and [Iterable]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Iterable]: Iterable.md
 | 
					[Iterable]: Iterable.md
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,13 @@
 | 
				
			|||||||
# Iterable interface
 | 
					# Iterable interface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The interface for anything that can be iterated, e.g. finite or infinite ordered set of data that can be accessed sequentially. Almost any data container in `Lyng` implements it: `List`, `Set`, `Buffer`, `RingBuffer`, `BitBuffer`, `Range` and many others are `Iterable`, also `Collection` and `Array` interfaces inherit it.
 | 
					The interface for anything that can be iterated, e.g. finite or infinite ordered set of data that can be accessed
 | 
				
			||||||
 | 
					sequentially. Almost any data container in `Lyng` implements it: `List`, `Set`, `Buffer`, `RingBuffer`, `BitBuffer`,
 | 
				
			||||||
 | 
					`Range` and many others are `Iterable`, also `Collection` and `Array` interfaces inherit it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
`Map` and `String` have `Iterable` members to access its contents too.
 | 
					`Map` and `String` have `Iterable` members to access its contents too.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Please see also [Collection] interface: many iterables are also collections, and it adds important features.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Definition:
 | 
					## Definition:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Iterable is a class that provides function that creates _the iterator_:
 | 
					Iterable is a class that provides function that creates _the iterator_:
 | 
				
			||||||
@ -23,7 +27,8 @@ Iterator itself is a simple interface that should provide only to method:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Just remember at this stage typed declarations are not yet supported.
 | 
					Just remember at this stage typed declarations are not yet supported.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Having `Iterable` in base classes allows to use it in for loop. Also, each `Iterable` has some utility functions available, for example
 | 
					Having `Iterable` in base classes allows to use it in for loop. Also, each `Iterable` has some utility functions
 | 
				
			||||||
 | 
					available, for example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    val r = 1..10  // Range is Iterable!  
 | 
					    val r = 1..10  // Range is Iterable!  
 | 
				
			||||||
    assertEquals( [9,10], r.takeLast(2).toList() )
 | 
					    assertEquals( [9,10], r.takeLast(2).toList() )
 | 
				
			||||||
@ -34,7 +39,8 @@ Having `Iterable` in base classes allows to use it in for loop. Also, each `Iter
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## joinToString
 | 
					## joinToString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This methods convert any iterable to a string joining string representation of each element, optionally transforming it and joining using specified suffix.
 | 
					This methods convert any iterable to a string joining string representation of each element, optionally transforming it
 | 
				
			||||||
 | 
					and joining using specified suffix.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Iterable.joinToString(suffux=' ', transform=null)
 | 
					    Iterable.joinToString(suffux=' ', transform=null)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -49,34 +55,56 @@ Here is the sample:
 | 
				
			|||||||
    assertEquals( (1..3).joinToString { it * 10 }, "10 20 30")
 | 
					    assertEquals( (1..3).joinToString { it * 10 }, "10 20 30")
 | 
				
			||||||
    >>> void
 | 
					    >>> void
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## `sum` and `sumBy`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					These, again, does the thing:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assertEquals( 6, [1,2,3].sum() )
 | 
				
			||||||
 | 
					    assertEquals( 12, [1,2,3].sumOf { it*2 } )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // sum of empty collections is null:
 | 
				
			||||||
 | 
					    assertEquals( null, [].sum() )
 | 
				
			||||||
 | 
					    assertEquals( null, [].sumOf { 2*it } )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    >>> void
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Instance methods:
 | 
					## Instance methods:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					| fun/method             | description                                                                     |
 | 
				
			||||||
| fun/method        | description                                                               |
 | 
					|------------------------|---------------------------------------------------------------------------------|
 | 
				
			||||||
|-------------------|---------------------------------------------------------------------------|
 | 
					| toList()               | create a list from iterable                                                     |
 | 
				
			||||||
| toList()          | create a list from iterable                                               |
 | 
					| toSet()                | create a set from iterable                                                      |
 | 
				
			||||||
| toSet()           | create a set from iterable                                                |
 | 
					| contains(i)            | check that iterable contains `i`                                                |
 | 
				
			||||||
| contains(i)       | check that iterable contains `i`                                          |
 | 
					| `i in iterator`        | same as `contains(i)`                                                           |
 | 
				
			||||||
| `i in iterator`   | same as `contains(i)`                                                     |
 | 
					| isEmpty()              | check iterable is empty                                                         |
 | 
				
			||||||
| isEmpty()         | check iterable is empty                                                   |
 | 
					| forEach(f)             | call f for each element                                                         |
 | 
				
			||||||
| forEach(f)        | call f for each element                                                   |
 | 
					| toMap()                | create a map from list of key-value pairs (arrays of 2 items or like)           |
 | 
				
			||||||
| toMap()           | create a map from list of key-value pairs (arrays of 2 items or like)     |
 | 
					| map(f)                 | create a list of values returned by `f` called for each element of the iterable |
 | 
				
			||||||
| map(f)            | create a list of values returned by `f` called for each element of the iterable |
 | 
					| indexOf(i)             | return index if the first encounter of i or a negative value if not found       |
 | 
				
			||||||
| indexOf(i)        | return index if the first encounter of i or a negative value if not found |
 | 
					| associateBy(kf)        | create a map where keys are returned by kf that will be called for each element |
 | 
				
			||||||
| associateBy(kf)   | create a map where keys are returned by kf that will be called for each element |
 | 
					| first                  | first element (1)                                                               |
 | 
				
			||||||
| first             | first element (1)                                                         |
 | 
					| last                   | last element (1)                                                                |
 | 
				
			||||||
| last              | last element (1)                                                          |
 | 
					| take(n)                | return [Iterable] of up to n first elements                                     |
 | 
				
			||||||
| take(n)           | return [Iterable] of up to n first elements                               |
 | 
					| taleLast(n)            | return [Iterable] of up to n last elements                                      |
 | 
				
			||||||
| taleLast(n)       | return [Iterable] of up to n last elements                                |
 | 
					| drop(n)                | return new [Iterable] without first n elements                                  |
 | 
				
			||||||
| drop(n)           | return new [Iterable] without first n elements                            |
 | 
					| dropLast(n)            | return new [Iterable] without last n elements                                   |
 | 
				
			||||||
| dropLast(n)       | return new [Iterable] without last n elements                             |
 | 
					| sum()                  | return sum of the collection applying `+` to its elements (3)                   |
 | 
				
			||||||
| joinToString(s,t) | convert iterable to string, see (2)                                       |
 | 
					| sumOf(predicate)       | sum of the modified collection items (3)                                        |
 | 
				
			||||||
 | 
					| sorted()               | return [List] with collection items sorted naturally                            |
 | 
				
			||||||
 | 
					| sortedWith(comparator) | sort using a comparator that compares elements (1)                              |
 | 
				
			||||||
 | 
					| sortedBy(predicate)    | sort by comparing results of the predicate function                             |
 | 
				
			||||||
 | 
					| joinToString(s,t)      | convert iterable to string, see (2)                                             |
 | 
				
			||||||
 | 
					| reversed()             | create a list containing items from this in reverse order                       |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(1)
 | 
					(1)
 | 
				
			||||||
: throws `NoSuchElementException` if there is no such element
 | 
					: throws `NoSuchElementException` if there is no such element
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(2)
 | 
					(2)
 | 
				
			||||||
: `joinToString(suffix=" ",transform=null)`: suffix is inserted between items if there are more than one, trasnfom is optional function applied to each item that must return result string for an item, otherwise `item.toString()` is used. 
 | 
					: `joinToString(suffix=" ",transform=null)`: suffix is inserted between items if there are more than one, trasnfom is
 | 
				
			||||||
 | 
					optional function applied to each item that must return result string for an item, otherwise `item.toString()` is used.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(3)
 | 
				
			||||||
 | 
					: sum of empty collection is `null`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun Iterable.toList(): List
 | 
					    fun Iterable.toList(): List
 | 
				
			||||||
    fun Iterable.toSet(): Set
 | 
					    fun Iterable.toSet(): Set
 | 
				
			||||||
@ -87,7 +115,6 @@ Here is the sample:
 | 
				
			|||||||
    fun Iterable.map(block: (Any?)->Void ): List
 | 
					    fun Iterable.map(block: (Any?)->Void ): List
 | 
				
			||||||
    fun Iterable.associateBy( keyMaker: (Any?)->Any): Map
 | 
					    fun Iterable.associateBy( keyMaker: (Any?)->Any): Map
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
## Abstract methods:
 | 
					## Abstract methods:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun iterator(): Iterator
 | 
					    fun iterator(): Iterator
 | 
				
			||||||
@ -102,7 +129,12 @@ Creates a list by iterating to the end. So, the Iterator should be finite to be
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
- [List], [Range], [Buffer](Buffer.md), [BitBuffer], [Buffer], [Set], [RingBuffer]
 | 
					- [List], [Range], [Buffer](Buffer.md), [BitBuffer], [Buffer], [Set], [RingBuffer]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Collection]: Collection.md
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[List]: List.md
 | 
					[List]: List.md
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Range]: Range.md
 | 
					[Range]: Range.md
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Set]: Set.md
 | 
					[Set]: Set.md
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[RingBuffer]: RingBuffer.md
 | 
					[RingBuffer]: RingBuffer.md
 | 
				
			||||||
							
								
								
									
										62
									
								
								docs/List.md
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								docs/List.md
									
									
									
									
									
								
							@ -92,22 +92,44 @@ Open end ranges remove head and tail elements:
 | 
				
			|||||||
    assert( [1, 2, 3] !== [1, 2, 3])
 | 
					    assert( [1, 2, 3] !== [1, 2, 3])
 | 
				
			||||||
    >>> void
 | 
					    >>> void
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## In-place sort
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					List could be sorted in place, just like [Collection] provide sorted copies, in a very like way:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val l1 = [6,3,1,9]
 | 
				
			||||||
 | 
					    l1.sort()
 | 
				
			||||||
 | 
					    assertEquals( [1,3,6,9], l1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    l1.sortBy { -it }
 | 
				
			||||||
 | 
					    assertEquals( [1,3,6,9].reversed(), l1)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    l1.sort() // 1 3 6 9
 | 
				
			||||||
 | 
					    l1.sortBy { it % 4 }
 | 
				
			||||||
 | 
					    // 1,3,6,9 gives, mod 4:
 | 
				
			||||||
 | 
					    // 1 3 2 1
 | 
				
			||||||
 | 
					    // we hope we got it also stable:
 | 
				
			||||||
 | 
					    assertEquals( [1,9,6,3], l1)
 | 
				
			||||||
 | 
					    >>> void
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Members
 | 
					## Members
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| name                          | meaning                               | type        |
 | 
					| name                          | meaning                                      | type        |
 | 
				
			||||||
|-------------------------------|---------------------------------------|-------------|
 | 
					|-------------------------------|----------------------------------------------|-------------|
 | 
				
			||||||
| `size`                        | current size                          | Int         |
 | 
					| `size`                        | current size                                 | Int         |
 | 
				
			||||||
| `add(elements...)`            | add one or more elements to the end   | Any         |
 | 
					| `add(elements...)`            | add one or more elements to the end          | Any         |
 | 
				
			||||||
| `insertAt(index,elements...)` | insert elements at position           | Int, Any    |
 | 
					| `insertAt(index,elements...)` | insert elements at position                  | Int, Any    |
 | 
				
			||||||
| `removeAt(index)`             | remove element at position            | Int         |
 | 
					| `removeAt(index)`             | remove element at position                   | Int         |
 | 
				
			||||||
| `remove(from,toNonInclusive)` | remove range from (incl) to (nonincl) | Int, Int    |
 | 
					| `remove(from,toNonInclusive)` | remove range from (incl) to (nonincl)        | Int, Int    |
 | 
				
			||||||
| `remove(Range)`               | remove range                          | Range       |
 | 
					| `remove(Range)`               | remove range                                 | Range       |
 | 
				
			||||||
| `removeLast()`                | remove last element                   |             |
 | 
					| `removeLast()`                | remove last element                          |             |
 | 
				
			||||||
| `removeLast(n)`               | remove n last elements                | Int         |
 | 
					| `removeLast(n)`               | remove n last elements                       | Int         |
 | 
				
			||||||
| `contains(element)`           | check the element is in the list (1)  |             |
 | 
					| `contains(element)`           | check the element is in the list (1)         |             |
 | 
				
			||||||
| `[index]`                     | get or set element at index           | Int         |
 | 
					| `[index]`                     | get or set element at index                  | Int         |
 | 
				
			||||||
| `[Range]`                     | get slice of the array (copy)         | Range       |
 | 
					| `[Range]`                     | get slice of the array (copy)                | Range       |
 | 
				
			||||||
| `+=`                          | append element(s)                     | List or Obj |
 | 
					| `+=`                          | append element(s) (2)                        | List or Obj |
 | 
				
			||||||
 | 
					| `sort()`                      | in-place sort, natural order                 | void        |
 | 
				
			||||||
 | 
					| 'sortBy(predicate)`           | in place sort bu `predicate` call result (3) | void        |
 | 
				
			||||||
 | 
					| `SortWith(comparator)         | in place sort using `comarator` function (4) | void        |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(1)
 | 
					(1)
 | 
				
			||||||
: optimized implementation that override `Array` one
 | 
					: optimized implementation that override `Array` one
 | 
				
			||||||
@ -116,7 +138,16 @@ Open end ranges remove head and tail elements:
 | 
				
			|||||||
: `+=` append either a single element, or all elements if the List or other Iterable
 | 
					: `+=` append either a single element, or all elements if the List or other Iterable
 | 
				
			||||||
instance is appended. If you want to append an Iterable object itself, use `add` instead.
 | 
					instance is appended. If you want to append an Iterable object itself, use `add` instead.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It inherits from [Iterable] too.
 | 
					(3)
 | 
				
			||||||
 | 
					: predicate is called on each element, and the returned values are used to sort in natural
 | 
				
			||||||
 | 
					order, e.g. is same as `list.sortWith { a,b -> predicate(a) <=> predicate(b) }`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(4)
 | 
				
			||||||
 | 
					: comparator callable takes tho arguments and must return: negative value when first is less, 
 | 
				
			||||||
 | 
					positive if first is greater, and zero if they are equal. For example, the equvalent comparator
 | 
				
			||||||
 | 
					for `sort()` will be `sort { a, b -> a <=> b }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It inherits from [Iterable] too and thus all iterable methods are applicable to any list.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Member inherited from Array
 | 
					## Member inherited from Array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -134,4 +165,5 @@ It inherits from [Iterable] too.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Range]: Range.md
 | 
					[Range]: Range.md
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Iterable]: Iterable.md
 | 
					[Iterable]: Iterable.md
 | 
				
			||||||
@ -764,15 +764,15 @@ thrown.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Typical builtin types that are containers (e.g. support `contains`):
 | 
					Typical builtin types that are containers (e.g. support `contains`):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| class      | notes                                          |
 | 
					| class        | notes                                          |
 | 
				
			||||||
|------------|------------------------------------------------|
 | 
					|--------------|------------------------------------------------|
 | 
				
			||||||
| Collection | contains an element (1)                        |
 | 
					| [Collection] | contains an element (1)                        |
 | 
				
			||||||
| Array      | faster maybe that Collection's                 |
 | 
					| Array        | faster maybe that Collection's                 |
 | 
				
			||||||
| List       | faster than Array's                            |
 | 
					| List         | faster than Array's                            |
 | 
				
			||||||
| String     | character in string or substring in string (3) |
 | 
					| String       | character in string or substring in string (3) |
 | 
				
			||||||
| Range      | object is included in the range (2)            |
 | 
					| Range        | object is included in the range (2)            |
 | 
				
			||||||
| Buffer     | byte is in buffer                              |
 | 
					| Buffer       | byte is in buffer                              |
 | 
				
			||||||
| RingBuffer | object is in buffer                            |
 | 
					| RingBuffer   | object is in buffer                            |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(1)
 | 
					(1)
 | 
				
			||||||
: Iterable is not the container as it can be infinite
 | 
					: Iterable is not the container as it can be infinite
 | 
				
			||||||
@ -1362,3 +1362,5 @@ See [math functions](math.md). Other general purpose functions are:
 | 
				
			|||||||
[parallelism]: parallelism.md
 | 
					[parallelism]: parallelism.md
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[RingBuffer]: RingBuffer.md
 | 
					[RingBuffer]: RingBuffer.md
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Collection]: Collection.md
 | 
				
			||||||
@ -21,7 +21,7 @@ import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
 | 
				
			|||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
 | 
					import org.jetbrains.kotlin.gradle.dsl.JvmTarget
 | 
				
			||||||
 | 
					
 | 
				
			||||||
group = "net.sergeych"
 | 
					group = "net.sergeych"
 | 
				
			||||||
version = "0.8.14-SNAPSHOT"
 | 
					version = "0.8.15-SNAPSHOT"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
buildscript {
 | 
					buildscript {
 | 
				
			||||||
    repositories {
 | 
					    repositories {
 | 
				
			||||||
 | 
				
			|||||||
@ -18,8 +18,8 @@
 | 
				
			|||||||
package net.sergeych.lyng.obj
 | 
					package net.sergeych.lyng.obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Collection is an iterator with `size`]
 | 
					 * Collection is an iterator with `size`
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
val ObjCollection = ObjClass("Collection", ObjIterable).apply {
 | 
					val ObjCollection = ObjClass("Collection", ObjIterable).apply {
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -119,12 +119,6 @@ val ObjIterable by lazy {
 | 
				
			|||||||
            ObjList(result)
 | 
					            ObjList(result)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//        addFn("drop" ) {
 | 
					 | 
				
			||||||
//            var n = requireOnlyArg<ObjInt>().value.toInt()
 | 
					 | 
				
			||||||
//            if( n < 0 ) raiseIllegalArgument("drop($n): should be positive")
 | 
					 | 
				
			||||||
//            val it = callMethod<>()
 | 
					 | 
				
			||||||
//        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        addFn("isEmpty") {
 | 
					        addFn("isEmpty") {
 | 
				
			||||||
            ObjBool(
 | 
					            ObjBool(
 | 
				
			||||||
                thisObj.invokeInstanceMethod(this, "iterator")
 | 
					                thisObj.invokeInstanceMethod(this, "iterator")
 | 
				
			||||||
@ -132,5 +126,21 @@ val ObjIterable by lazy {
 | 
				
			|||||||
                    .not()
 | 
					                    .not()
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        addFn("sortedWith") {
 | 
				
			||||||
 | 
					            val list = thisObj.callMethod<ObjList>(this, "toList")
 | 
				
			||||||
 | 
					            val comparator = requireOnlyArg<Statement>()
 | 
				
			||||||
 | 
					            list.quicksort { a, b ->
 | 
				
			||||||
 | 
					                comparator.call(this, a, b).toInt()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            list
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        addFn("reversed") {
 | 
				
			||||||
 | 
					            val list = thisObj.callMethod<ObjList>(this, "toList")
 | 
				
			||||||
 | 
					            list.list.reverse()
 | 
				
			||||||
 | 
					            list
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -18,6 +18,7 @@
 | 
				
			|||||||
package net.sergeych.lyng.obj
 | 
					package net.sergeych.lyng.obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.sergeych.lyng.Scope
 | 
					import net.sergeych.lyng.Scope
 | 
				
			||||||
 | 
					import net.sergeych.lyng.Statement
 | 
				
			||||||
import net.sergeych.lyng.statement
 | 
					import net.sergeych.lyng.statement
 | 
				
			||||||
import net.sergeych.lynon.LynonDecoder
 | 
					import net.sergeych.lynon.LynonDecoder
 | 
				
			||||||
import net.sergeych.lynon.LynonEncoder
 | 
					import net.sergeych.lynon.LynonEncoder
 | 
				
			||||||
@ -127,6 +128,33 @@ class ObjList(val list: MutableList<Obj> = mutableListOf()) : Obj() {
 | 
				
			|||||||
        return list.map { it.toKotlin(scope) }
 | 
					        return list.map { it.toKotlin(scope) }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    suspend fun quicksort(compare: suspend (Obj, Obj) -> Int) = quicksort(compare, 0, list.size - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    suspend fun quicksort(compare: suspend (Obj, Obj) -> Int, left: Int, right: Int) {
 | 
				
			||||||
 | 
					        if (left >= right) return
 | 
				
			||||||
 | 
					        var i = left
 | 
				
			||||||
 | 
					        var j = right
 | 
				
			||||||
 | 
					        val pivot = list[left]
 | 
				
			||||||
 | 
					        while (i < j) {
 | 
				
			||||||
 | 
					            // Сдвигаем j влево, пока элемент меньше pivot
 | 
				
			||||||
 | 
					            while (i < j && compare(list[j], pivot) >= 0) {
 | 
				
			||||||
 | 
					                j--
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // Сдвигаем i вправо, пока элемент больше pivot
 | 
				
			||||||
 | 
					            while (i < j && compare(list[i], pivot) <= 0) {
 | 
				
			||||||
 | 
					                i++
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (i < j) {
 | 
				
			||||||
 | 
					                list.swap(i, j)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // После завершения i == j, ставим pivot на своё место
 | 
				
			||||||
 | 
					        list.swap(left, i)
 | 
				
			||||||
 | 
					        // Рекурсивно сортируем левую и правую части
 | 
				
			||||||
 | 
					        quicksort(compare, left, i - 1)
 | 
				
			||||||
 | 
					        quicksort(compare, i + 1, right)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun hashCode(): Int {
 | 
					    override fun hashCode(): Int {
 | 
				
			||||||
        // check?
 | 
					        // check?
 | 
				
			||||||
        return list.hashCode()
 | 
					        return list.hashCode()
 | 
				
			||||||
@ -235,8 +263,23 @@ class ObjList(val list: MutableList<Obj> = mutableListOf()) : Obj() {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                self
 | 
					                self
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            addFn("sortWith") {
 | 
				
			||||||
 | 
					                val comparator = requireOnlyArg<Statement>()
 | 
				
			||||||
 | 
					                thisAs<ObjList>().quicksort { a, b -> comparator.call(this, a, b).toInt() }
 | 
				
			||||||
 | 
					                ObjVoid
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Расширение MutableList для удобного обмена элементами
 | 
				
			||||||
 | 
					fun <T>MutableList<T>.swap(i: Int, j: Int) {
 | 
				
			||||||
 | 
					    if (i in indices && j in indices) {
 | 
				
			||||||
 | 
					        val temp = this[i]
 | 
				
			||||||
 | 
					        this[i] = this[j]
 | 
				
			||||||
 | 
					        this[j] = temp
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -103,10 +103,46 @@ fun Iterable.all(predicate): Bool {
 | 
				
			|||||||
    !any { !predicate(it) }
 | 
					    !any { !predicate(it) }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun Iterable.sum() {
 | 
				
			||||||
 | 
					    val i = iterator()
 | 
				
			||||||
 | 
					    if( i.hasNext() ) {
 | 
				
			||||||
 | 
					        var result = i.next()
 | 
				
			||||||
 | 
					        while( i.hasNext() ) result += i.next()
 | 
				
			||||||
 | 
					        result
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else null
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun Iterable.sumOf(f) {
 | 
				
			||||||
 | 
					    val i = iterator()
 | 
				
			||||||
 | 
					    if( i.hasNext() ) {
 | 
				
			||||||
 | 
					        var result = f(i.next())
 | 
				
			||||||
 | 
					        while( i.hasNext() ) result += f(i.next())
 | 
				
			||||||
 | 
					        result
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else null
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun Iterable.sorted() {
 | 
				
			||||||
 | 
					    sortedWith { a, b -> a <=> b }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun Iterable.sortedBy(predicate) {
 | 
				
			||||||
 | 
					    sortedWith { a, b -> predicate(a) <=> predicate(b) }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fun List.toString() {
 | 
					fun List.toString() {
 | 
				
			||||||
    "[" + joinToString(",") + "]"
 | 
					    "[" + joinToString(",") + "]"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun List.sortBy(predicate) {
 | 
				
			||||||
 | 
					    sortWith { a, b -> predicate(a) <=> predicate(b) }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun List.sort() {
 | 
				
			||||||
 | 
					    sortWith { a, b -> a <=> b }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StackTraceEntry(
 | 
					class StackTraceEntry(
 | 
				
			||||||
    val sourceName: String,
 | 
					    val sourceName: String,
 | 
				
			||||||
    val line: Int,
 | 
					    val line: Int,
 | 
				
			||||||
@ -125,5 +161,6 @@ fun Exception.printStackTrace() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
""".trimIndent()
 | 
					""".trimIndent()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -3095,10 +3095,12 @@ class ScriptTest {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    fun testOverridenListToString() = runTest {
 | 
					    fun testOverridenListToString() = runTest {
 | 
				
			||||||
        eval("""
 | 
					        eval(
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
            val x = [1,2,3]
 | 
					            val x = [1,2,3]
 | 
				
			||||||
            assertEquals( "[1,2,3]", x.toString() )
 | 
					            assertEquals( "[1,2,3]", x.toString() )
 | 
				
			||||||
        """.trimIndent())
 | 
					        """.trimIndent()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
@ -3131,7 +3133,8 @@ class ScriptTest {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    fun testThisInClosure() = runTest {
 | 
					    fun testThisInClosure() = runTest {
 | 
				
			||||||
        eval("""
 | 
					        eval(
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
            fun Iterable.sum2by(f) {
 | 
					            fun Iterable.sum2by(f) {
 | 
				
			||||||
                var acc = null
 | 
					                var acc = null
 | 
				
			||||||
                for( x in this ) {
 | 
					                for( x in this ) {
 | 
				
			||||||
@ -3147,12 +3150,14 @@ class ScriptTest {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            assertEquals(60, T([1,2,3], 10).sum())
 | 
					            assertEquals(60, T([1,2,3], 10).sum())
 | 
				
			||||||
        """.trimIndent())
 | 
					        """.trimIndent()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    fun testThisInFlowClosure() = runTest {
 | 
					    fun testThisInFlowClosure() = runTest {
 | 
				
			||||||
        eval("""
 | 
					        eval(
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
            class T(val coll, val factor) {
 | 
					            class T(val coll, val factor) {
 | 
				
			||||||
                fun seq() {
 | 
					                fun seq() {
 | 
				
			||||||
                    flow {
 | 
					                    flow {
 | 
				
			||||||
@ -3163,7 +3168,50 @@ class ScriptTest {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            assertEquals([10,20,30], T([1,2,3], 10).seq().toList())
 | 
					            assertEquals([10,20,30], T([1,2,3], 10).seq().toList())
 | 
				
			||||||
        """.trimIndent())
 | 
					        """.trimIndent()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    fun testSum() = runTest {
 | 
				
			||||||
 | 
					        eval(
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            assertEquals(1, [1].sum())
 | 
				
			||||||
 | 
					            assertEquals(null, [].sum())
 | 
				
			||||||
 | 
					            assertEquals(6, [1,2,3].sum())
 | 
				
			||||||
 | 
					            assertEquals(30, [3].sumOf { it * 10 })
 | 
				
			||||||
 | 
					            assertEquals(null, [].sumOf { it * 10 })
 | 
				
			||||||
 | 
					            assertEquals(60, [1,2,3].sumOf { it * 10 })
 | 
				
			||||||
 | 
					        """.trimIndent()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    fun testSort() = runTest {
 | 
				
			||||||
 | 
					        eval("""
 | 
				
			||||||
 | 
					            val coll = [5,4,1,7]
 | 
				
			||||||
 | 
					            assertEquals( [1,4,5,7], coll.sortedWith { a,b -> a <=> b })
 | 
				
			||||||
 | 
					            assertEquals( [1,4,5,7], coll.sorted())
 | 
				
			||||||
 | 
					            assertEquals( [7,5,4,1], coll.sortedBy { -it })
 | 
				
			||||||
 | 
					            assertEquals( [1,4,5,7], coll.sortedBy { -it }.reversed())
 | 
				
			||||||
 | 
					        """.trimIndent()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    fun testListSortInPlace() = runTest {
 | 
				
			||||||
 | 
					        eval("""
 | 
				
			||||||
 | 
					            val l1 = [6,3,1,9]
 | 
				
			||||||
 | 
					            l1.sort()
 | 
				
			||||||
 | 
					            assertEquals( [1,3,6,9], l1)
 | 
				
			||||||
 | 
					            l1.sortBy { -it }
 | 
				
			||||||
 | 
					            assertEquals( [1,3,6,9].reversed(), l1)
 | 
				
			||||||
 | 
					            l1.sort()
 | 
				
			||||||
 | 
					            l1.sortBy { it % 4 }
 | 
				
			||||||
 | 
					            // 1,3,6,9
 | 
				
			||||||
 | 
					            // 1 3 2 1
 | 
				
			||||||
 | 
					            // we hope we got it also stable:
 | 
				
			||||||
 | 
					            assertEquals( [1,9,6,3], l1)
 | 
				
			||||||
 | 
					        """)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user