struct

Slice(T)

Inherits Comparable / Indexable::Mutable / Indexable / Enumerable / Iterable / Struct / Value / Object

A Slice is a Pointer with an associated size.

While a pointer is unsafe because no bound checks are performed when reading from and writing to it, reading from and writing to a slice involve bound checks. In this way, a slice is a safe alternative to Pointer.

A Slice can be created as read-only: trying to write to it will raise. For example the slice of bytes returned by String#to_slice is read-only.

Constructors

additive_identity

Returns the additive identity of this type.

This is an empty slice.

Source
empty

Creates an empty slice.

slice = Slice(UInt8).empty
slice.size # => 0
Source
join(slices : Indexable(Slice)) : Slice

Returns a new slice that has the elements from slices joined together.

Slice.join([Slice[1, 2], Slice[3, 4, 5]])        # => Slice[1, 2, 3, 4, 5]
Slice.join({Slice[1], Slice['a'], Slice["xyz"]}) # => Slice[1, 'a', "xyz"]

See also: #+(other : Slice).

Source
new(pointer : Pointer(T), size : Int, *, read_only : Bool = false)

Creates a slice to the given pointer, bounded by the given size. This method does not allocate heap memory.

ptr = Pointer.malloc(9) { |i| ('a'.ord + i).to_u8 }

slice = Slice.new(ptr, 3)
slice.size # => 3
slice      # => Bytes[97, 98, 99]

String.new(slice) # => "abc"
Source
new(size : Int, value : T, *, read_only = false)

Allocates size * sizeof(T) bytes of heap memory initialized to value and returns a slice pointing to that memory.

The memory is allocated by the GC, so when there are no pointers to this memory, it will be automatically freed.

slice = Slice.new(3, 10)
slice # => Slice[10, 10, 10]
Source
new(size : Int, *, read_only = false)

Allocates size * sizeof(T) bytes of heap memory initialized to zero and returns a slice pointing to that memory.

The memory is allocated by the GC, so when there are no pointers to this memory, it will be automatically freed.

Only works for primitive integers and floats (UInt8, Int32, Float64, etc.)

slice = Slice(UInt8).new(3)
slice # => Bytes[0, 0, 0]
Source
new(size : Int, *, read_only = false, &)

Allocates size * sizeof(T) bytes of heap memory initialized to the value returned by the block (which is invoked once with each index in the range 0...size) and returns a slice pointing to that memory.

The memory is allocated by the GC, so when there are no pointers to this memory, it will be automatically freed.

slice = Slice.new(3) { |i| i + 10 }
slice # => Slice[10, 11, 12]
Source

Class methods

literal(*args)

Constructs a read-only Slice constant from the given args. The slice contents are stored in the program's read-only data section.

If T is specified, it must be one of the Number::Primitive types and cannot be a union. The args must all be number literals that fit into T's range, as if they are autocasted into T.

If T is not specified, it is inferred from args, which must all be number literals of the same type, and cannot be empty.

x = Slice(UInt8).literal(0, 1, 4, 9, 16, 25)
x            # => Slice[0, 1, 4, 9, 16, 25]
x.read_only? # => true

Slice.literal(1_u8, 2_u8, 3_u8) # => Bytes[1, 2, 3]
Source

Instance methods

+(offset : Int) : Slice(T)

Returns a new slice that is offset elements apart from this slice.

slice = Slice.new(5) { |i| i + 10 }
slice # => Slice[10, 11, 12, 13, 14]

slice2 = slice + 2
slice2 # => Slice[12, 13, 14]
Source
+(other : Slice) : Slice

Returns a new slice that has self's elements followed by other's elements.

Slice[1, 2] + Slice[3, 4, 5]          # => Slice[1, 2, 3, 4, 5]
Slice[1, 2, 3] + Slice['a', 'b', 'c'] # => Slice[1, 2, 3, 'a', 'b', 'c']

See also: Slice.join to join multiple slices at once without creating intermediate results.

Source
<=>(other : Slice(U)) forall U

Combined comparison operator.

Returns a negative number, 0, or a positive number depending on whether self is less than other, equals other.

It compares the elements of both slices in the same position using the <=> operator. As soon as one of such comparisons returns a non-zero value, that result is the return value of the comparison.

If all elements are equal, the comparison is based on the size of the arrays.

Bytes[8] <=> Bytes[1, 2, 3] # => 7
Bytes[2] <=> Bytes[4, 2, 3] # => -2
Bytes[1, 2] <=> Bytes[1, 2] # => 0
Source
==(other : Slice(U)) : Bool forall U

Returns true if self and other have the same size and all their elements are equal, false otherwise.

Bytes[1, 2] == Bytes[1, 2]    # => true
Bytes[1, 3] == Bytes[1, 2]    # => false
Bytes[1, 2] == Bytes[1, 2, 3] # => false
Source
[](start : Int, count : Int) : Slice(T)

Returns a new slice that starts at start elements from this slice's start, and of exactly count size.

Negative start is added to #size, thus it's treated as index counting from the end of the array, -1 designating the last element.

Raises ArgumentError if count is negative. Raises IndexError if the new slice falls outside this slice.

slice = Slice.new(5) { |i| i + 10 }
slice # => Slice[10, 11, 12, 13, 14]

slice[1, 3]   # => Slice[11, 12, 13]
slice[1, 33]  # raises IndexError
slice[-3, 2]  # => Slice[12, 13]
slice[-3, 10] # raises IndexError
Source
[](range : Range) : Slice(T)

Returns a new slice with the elements in the given range.

The first element in the returned slice is self[range.begin] followed by the next elements up to index range.end (or self[range.end - 1] if the range is exclusive). If there are fewer elements in self, the returned slice is shorter than range.size.

a = Slice["a", "b", "c", "d", "e"]
a[1..3] # => Slice["b", "c", "d"]

Negative indices count backward from the end of the slice (-1 is the last element). Additionally, an empty slice is returned when the starting index for an element range is at the end of the slice.

Raises IndexError if the new slice falls outside this slice.

slice = Slice.new(5) { |i| i + 10 }
slice # => Slice[10, 11, 12, 13, 14]

slice[1..3]  # => Slice[11, 12, 13]
slice[1..33] # raises IndexError
Source
[]=(index : Int, value : T) : T

Sets the given value at the given index. Returns value.

Negative indices can be used to start counting from the end of the container. Raises IndexError if trying to set an element outside the container's range.

ary = [1, 2, 3]
ary[0] = 5
ary # => [5, 2, 3]

ary[3] = 5 # raises IndexError

Raises if this slice is read-only.

Source
[]?(start : Int, count : Int) : Slice(T) | Nil

Returns a new slice that starts at start elements from this slice's start, and of exactly count size.

Negative start is added to #size, thus it's treated as index counting from the end of the array, -1 designating the last element.

Raises ArgumentError if count is negative. Returns nil if the new slice falls outside this slice.

slice = Slice.new(5) { |i| i + 10 }
slice # => Slice[10, 11, 12, 13, 14]

slice[1, 3]?   # => Slice[11, 12, 13]
slice[1, 33]?  # => nil
slice[-3, 2]?  # => Slice[12, 13]
slice[-3, 10]? # => nil
Source
[]?(range : Range)

Returns a new slice with the elements in the given range.

Negative indices count backward from the end of the slice (-1 is the last element). Additionally, an empty slice is returned when the starting index for an element range is at the end of the slice.

Returns nil if the new slice falls outside this slice.

slice = Slice.new(5) { |i| i + 10 }
slice # => Slice[10, 11, 12, 13, 14]

slice[1..3]?  # => Slice[11, 12, 13]
slice[1..33]? # => nil
Source
bytesize
Source
clone

Returns a deep copy of this slice.

This method allocates memory for the slice copy and stores the return values from calling #clone on each item.

Source
copy_from(source : Pointer(T), count) : Nil
Source
copy_from(source : self) : Nil

Copies the contents of source into this slice.

Raises IndexError if the destination slice cannot fit the data being transferred.

Source
copy_to(target : Pointer(T), count) : Nil
Source
copy_to(target : self) : Nil

Copies the contents of this slice into target.

Raises IndexError if the destination slice cannot fit the data being transferred e.g. dest.size < self.size.

src = Slice['a', 'a', 'a']
dst = Slice['b', 'b', 'b', 'b', 'b']
src.copy_to dst
dst             # => Slice['a', 'a', 'a', 'b', 'b']
dst.copy_to src # raises IndexError
Source
dup

Returns a shallow copy of this slice.

This method allocates memory for the slice copy and duplicates the values.

Source
fill(value : T, start : Int, count : Int) : self

Replaces count or less (if there aren't enough) elements starting at the given start index with value. Returns self.

Negative values of start count from the end of the container.

Raises IndexError if the start index is out of range.

Raises ArgumentError if count is negative.

array = [1, 2, 3, 4, 5]
array.fill(9, 2, 2) # => [1, 2, 9, 9, 5]
array               # => [1, 2, 9, 9, 5]

Raises if this slice is read-only.

Source
fill(value : T, range : Range) : self

Replaces the elements within the given range with value. Returns self.

Negative indices count backward from the end of the container.

Raises IndexError if the starting index is out of range.

array = [1, 2, 3, 4, 5]
array.fill(9, 2..3) # => [1, 2, 9, 9, 5]
array               # => [1, 2, 9, 9, 5]

Raises if this slice is read-only.

Source
fill(value : T) : self

Replaces every element in self with the given value. Returns self.

array = [1, 2, 3, 4]
array.fill(2) # => [2, 2, 2, 2]
array         # => [2, 2, 2, 2]

Raises if this slice is read-only.

Source
fill(start : Int, count : Int, & : Int32 -> T) : self

Yields each index of self, starting at start and for count times (or less if there aren't enough elements), to the given block and then assigns the block's value in that position. Returns self.

Negative values of start count from the end of the container.

Has no effect if count is zero or negative.

Raises IndexError if start is outside the array range.

a = [1, 2, 3, 4, 5, 6]
a.fill(2, 3) { |i| i * i * i } # => [1, 2, 8, 27, 64, 6]

Raises if this slice is read-only.

Source
fill(range : Range, & : Int32 -> T) : self

Yields each index of self, in the given range, to the given block and then assigns the block's value in that position. Returns self.

Negative indices count backward from the end of the container.

Raises IndexError if the starting index is out of range.

a = [1, 2, 3, 4, 5, 6]
a.fill(2..4) { |i| i * i * i } # => [1, 2, 8, 27, 64, 6]

Raises if this slice is read-only.

Source
fill(*, offset : Int = 0, & : Int32 -> T) : self

Yields each index of self to the given block and then assigns the block's value in that position. Returns self.

Accepts an optional offset parameter, which tells the block to start counting from there.

array = [2, 1, 1, 1]
array.fill { |i| i * i }            # => [0, 1, 4, 9]
array                               # => [0, 1, 4, 9]
array.fill(offset: 3) { |i| i * i } # => [9, 16, 25, 36]
array                               # => [9, 16, 25, 36]

Raises if this slice is read-only.

Source
hash(hasher)

See Object#hash(hasher)

Source
hexdump(io : IO)

Writes a hexdump of this slice to the given io.

self must be a Slice(UInt8). To call this method on other Slices, #to_unsafe_bytes should be used first.

This method is specially useful for debugging binary data and incoming/outgoing data in protocols.

Returns the number of bytes written to io.

slice = UInt8.slice(97, 62, 63, 8, 255)
slice.hexdump(STDOUT)

Prints:

00000000  61 3e 3f 08 ff                                    a>?..
Source
hexdump

Returns a hexdump of this slice.

self must be a Slice(UInt8). To call this method on other Slices, #to_unsafe_bytes should be used first.

This method is specially useful for debugging binary data and incoming/outgoing data in protocols.

slice = UInt8.slice(97, 62, 63, 8, 255)
slice.hexdump # => "00000000  61 3e 3f 08 ff                                    a>?..\n"

# assume little-endian system
slice = Int16.slice(97, 62, 1000, -2)
slice.to_unsafe_bytes.hexdump # => "00000000  61 00 3e 00 e8 03 fe ff                           a.>.....\n"
Source
hexstring

Returns a hexstring representation of this slice.

self must be a Slice(UInt8). To call this method on other Slices, #to_unsafe_bytes should be used first.

UInt8.slice(97, 62, 63, 8, 255).hexstring # => "613e3f08ff"

# assume little-endian system
Int16.slice(97, 62, 1000, -2).to_unsafe_bytes.hexstring # => "61003e00e803feff"
Source
index(object, offset : Int = 0)

Returns the index of the first appearance of object in self starting from the given offset, or nil if object is not in self.

[1, 2, 3, 1, 2, 3].index(2, offset: 2) # => 4
Source
inspect(io : IO) : Nil

Appends this struct's name and instance variables names and values to the given IO.

struct Point
  def initialize(@x : Int32, @y : Int32)
  end
end

p1 = Point.new 1, 2
p1.to_s    # "Point(@x=1, @y=2)"
p1.inspect # "Point(@x=1, @y=2)"
Source
map(*, read_only = false, & : T -> _)

Returns a new slice where elements are mapped by the given block.

slice = Slice[1, 2.5, "a"]
slice.map &.to_s # => Slice["1", "2.5", "a"]
Source
map!

Invokes the given block for each element of self, replacing the element with the value returned by the block. Returns self.

a = [1, 2, 3]
a.map! { |x| x * x }
a # => [1, 4, 9]

Raises if this slice is read-only.

Source
map_with_index(offset = 0, *, read_only = false, & : T, Int32 -> _)

Like map, but the block gets passed both the element and its index.

Accepts an optional offset parameter, which tells it to start counting from there.

Source
map_with_index!(offset = 0, & : T, Int32 -> _) : self

Like #map!, but the block gets passed both the element and its index.

Accepts an optional offset parameter, which tells it to start counting from there.

gems = ["crystal", "pearl", "diamond"]
gems.map_with_index! { |gem, i| "#{i}: #{gem}" }
gems # => ["0: crystal", "1: pearl", "2: diamond"]

Raises if this slice is read-only.

Source
move_from(source : Pointer(T), count) : Nil
Source
move_from(source : self) : Nil

Moves the contents of source into this slice. source and self may overlap; the copy is always done in a non-destructive manner.

Raises IndexError if the destination slice cannot fit the data being transferred.

Source
move_to(target : Pointer(T), count) : Nil
Source
move_to(target : self) : Nil

Moves the contents of this slice into target. target and self may overlap; the copy is always done in a non-destructive manner.

Raises IndexError if the destination slice cannot fit the data being transferred e.g. dest.size < self.size.

src = Slice['a', 'a', 'a']
dst = Slice['b', 'b', 'b', 'b', 'b']
src.move_to dst
dst             # => Slice['a', 'a', 'a', 'b', 'b']
dst.move_to src # raises IndexError

See also: Pointer#move_to.

Source
pretty_print(pp) : Nil
Source
read_only?

Returns true if this slice cannot be written to.

Source
reverse!

Reverses in-place all the elements of self. Returns self.

Raises if this slice is read-only.

Source
rotate!(n : Int = 1) : self

Shifts all elements of self to the left n times. Returns self.

a1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a2 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a3 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

a1.rotate!
a2.rotate!(1)
a3.rotate!(3)

a1 # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
a2 # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
a3 # => [3, 4, 5, 6, 7, 8, 9, 0, 1, 2]

Raises if this slice is read-only.

Source
same?(other : self) : Bool

Returns true if self and other point to the same memory, i.e. pointer and size are identical.

slice = Slice[1, 2, 3]
slice.same?(slice)           # => true
slice == Slice[1, 2, 3]      # => false
slice.same?(slice + 1)       # => false
(slice + 1).same?(slice + 1) # => true
slice.same?(slice[0, 2])     # => false
Source
shuffle!(random : Random | Nil = nil) : self

Modifies self by randomizing the order of elements in the collection. Returns self.

a = [1, 2, 3, 4, 5]
a.shuffle! # => [3, 5, 2, 4, 1]
a          # => [3, 5, 2, 4, 1]

Uses the random instance when provided if the randomness needs to be controlled or to follow some traits. For example the following shuffle will always result in the same order:

a = [1, 2, 3, 4, 5]
a.shuffle!(Random.new(42)) # => [3, 2, 4, 5, 1]
a.shuffle!(Random.new(42)) # => [3, 2, 4, 5, 1]
a                          # => [3, 2, 4, 5, 1]

Raises if this slice is read-only.

Source
size

Returns the size of this slice.

Slice(UInt8).new(3).size # => 3
Source
sort

Returns a new instance with all elements sorted based on the return value of their comparison method T#<=> (see Comparable#<=>), using a stable sort algorithm.

a = Slice[3, 1, 2]
a.sort # => Slice[1, 2, 3]
a      # => Slice[3, 1, 2]

See #sort! for details on the sorting mechanism.

Raises ArgumentError if the comparison between any two elements returns nil.

Source
sort

Returns a new instance with all elements sorted based on the comparator in the given block, using a stable sort algorithm.

a = Slice[3, 1, 2]
b = a.sort { |a, b| b <=> a }

b # => Slice[3, 2, 1]
a # => Slice[3, 1, 2]

See Indexable::Mutable#sort!(&block : T, T -> U) for details on the sorting mechanism.

Raises ArgumentError if for any two elements the block returns nil.

Source
sort!

Sorts all elements in self based on the return value of the comparison method T#<=> (see Comparable#<=>), using a stable sort algorithm.

slice = Slice[3, 1, 2]
slice.sort!
slice # => Slice[1, 2, 3]

This sort operation modifies self. See #sort for a non-modifying option that allocates a new instance.

The sort mechanism is implemented as merge sort. It is stable, which is typically a good default.

Stability means that two elements which compare equal (i.e. a <=> b == 0) keep their original relation. Stable sort guarantees that [a, b].sort! always results in [a, b] (given they compare equal). With unstable sort, the result could also be [b, a].

If stability is expendable, #unstable_sort! provides a performance advantage over stable sort. As an optimization, if T is any primitive integer type, Char, any enum type, any Pointer instance, Symbol, or Time::Span, then an unstable sort is automatically used.

Raises ArgumentError if the comparison between any two elements returns nil.

Source
sort!

Sorts all elements in self based on the comparator in the given block, using a stable sort algorithm.

slice = Slice[3, 1, 2]
# This is a reverse sort (forward sort would be `a <=> b`)
slice.sort! { |a, b| b <=> a }
slice # => Slice[3, 2, 1]

The block must implement a comparison between two elements a and b, where a < b outputs a negative value, a == b outputs 0, and a > b outputs a positive value. The comparison operator (Comparable#<=>) can be used for this.

The block's output type must be <= Int32?, but returning an actual nil value is an error.

This sort operation modifies self. See #sort(&block : T, T -> U) for a non-modifying option that allocates a new instance.

The sort mechanism is implemented as merge sort. It is stable, which is typically a good default.

Stability means that two elements which compare equal (i.e. a <=> b == 0) keep their original relation. Stable sort guarantees that [a, b].sort! always results in [a, b] (given they compare equal). With unstable sort, the result could also be [b, a].

If stability is expendable, #unstable_sort!(&block : T, T -> U) provides a performance advantage over stable sort.

Raises ArgumentError if for any two elements the block returns nil.

Source
sort_by

Returns a new instance with all elements sorted by the output value of the block. The output values are compared via the comparison method T#<=> (see Comparable#<=>), using a stable sort algorithm.

a = Slice["apple", "pear", "fig"]
b = a.sort_by { |word| word.size }
b # => Slice["fig", "pear", "apple"]
a # => Slice["apple", "pear", "fig"]

If stability is expendable, #unstable_sort_by(&block : T -> _) provides a performance advantage over stable sort.

See Indexable::Mutable#sort_by!(&block : T -> _) for details on the sorting mechanism.

Raises ArgumentError if the comparison between any two comparison values returns nil.

Source
sort_by!

Modifies self by sorting all elements. The given block is called for each element, then the comparison method <=> is called on the object returned from the block to determine sort order.

a = Slice["apple", "pear", "fig"]
a.sort_by! { |word| word.size }
a # => Slice["fig", "pear", "apple"]
Source
swap(index0 : Int, index1 : Int) : self

Swaps the elements at index0 and index1. Returns self.

Negative indices can be used to start counting from the end of the container. Raises IndexError if either index is out of bounds.

a = ["first", "second", "third"]
a.swap(1, 2)  # => ["first", "third", "second"]
a             # => ["first", "third", "second"]
a.swap(0, -1) # => ["second", "third", "first"]
a             # => ["second", "third", "first"]
a.swap(2, 3)  # raises IndexError

Raises if this slice is read-only.

Source
to_a

Returns an Array with all the elements in the collection.

(1..5).to_a # => [1, 2, 3, 4, 5]
Source
to_s(io : IO) : Nil

Same as #inspect(io).

Source
to_slice
Source
to_unsafe

Returns this slice's pointer.

slice = Slice.new(3, 10)
slice.to_unsafe[0] # => 10
Source
to_unsafe_bytes

Returns a new Bytes pointing at the same contents as self.

WARNING: This method is unsafe: the returned slice is writable if self is also writable, and modifications through the returned slice may violate the binary representations of Crystal objects. Additionally, the same elements may produce different results depending on the system endianness.

# assume little-endian system
ints = Slice[0x01020304, 0x05060708]
bytes = ints.to_unsafe_bytes # => Bytes[0x04, 0x03, 0x02, 0x01, 0x08, 0x07, 0x06, 0x05]
bytes[2] = 0xAD
ints # => Slice[0x01AD0304, 0x05060708]
Source
to_yaml(yaml : YAML::Nodes::Builder) : Nil
Source
unsafe_fetch(index : Int) : T

Returns the element at the given index, without doing any bounds check.

Indexable makes sure to invoke this method with index in 0...size, so converting negative indices to positive ones is not needed here.

Clients never invoke this method directly. Instead, they access elements with #[](index) and #[]?(index).

This method should only be directly invoked if you are absolutely sure the index is in bounds, to avoid a bounds check for a small boost of performance.

Source
unsafe_put(index : Int, value : T)

Sets the element at the given index to value, without doing any bounds check.

Indexable::Mutable makes sure to invoke this method with index in 0...size, so converting negative indices to positive ones is not needed here.

Clients never invoke this method directly. Instead, they modify elements with #[]=(index, value).

This method should only be directly invoked if you are absolutely sure the index is in bounds, to avoid a bounds check for a small boost of performance.

Source
unsafe_slice_of(type : U.class) : Slice(U) forall U

Returns a new Slice pointing at the same contents as self, but reinterpreted as elements of the given type.

The returned slice never refers to more memory than self; if the last bytes of self do not fit into a U, they are excluded from the returned slice.

WARNING: This method is unsafe: elements are reinterpreted using #unsafe_as, and the resulting slice may not be properly aligned. Additionally, the same elements may produce different results depending on the system endianness.

# assume little-endian system
bytes = Bytes[0x01, 0x02, 0x03, 0x04, 0xFF, 0xFE]
bytes.unsafe_slice_of(Int8)  # => Slice[1_i8, 2_i8, 3_i8, 4_i8, -1_i8, -2_i8]
bytes.unsafe_slice_of(Int16) # => Slice[513_i16, 1027_i16, -257_i16]
bytes.unsafe_slice_of(Int32) # => Slice[0x04030201]
Source
unstable_sort

Returns a new instance with all elements sorted based on the return value of their comparison method T#<=> (see Comparable#<=>), using an unstable sort algorithm.

a = Slice[3, 1, 2]
a.unstable_sort # => Slice[1, 2, 3]
a               # => Slice[3, 1, 2]

See Indexable::Mutable#unstable_sort! for details on the sorting mechanism.

Raises ArgumentError if the comparison between any two elements returns nil.

Source
unstable_sort

Returns a new instance with all elements sorted based on the comparator in the given block, using an unstable sort algorithm.

a = Slice[3, 1, 2]
b = a.unstable_sort { |a, b| b <=> a }

b # => Slice[3, 2, 1]
a # => Slice[3, 1, 2]

See Indexable::Mutable#unstable_sort!(&block : T, T -> U) for details on the sorting mechanism.

Raises ArgumentError if for any two elements the block returns nil.

Source
unstable_sort!

Sorts all elements in self based on the return value of the comparison method T#<=> (see Comparable#<=>), using an unstable sort algorithm..

slice = Slice[3, 1, 2]
slice.unstable_sort!
slice # => Slice[1, 2, 3]

This sort operation modifies self. See #unstable_sort for a non-modifying option that allocates a new instance.

The sort mechanism is implemented as introsort. It does not guarantee stability between equally comparing elements. This offers higher performance but may be unexpected in some situations.

Stability means that two elements which compare equal (i.e. a <=> b == 0) keep their original relation. Stable sort guarantees that [a, b].sort! always results in [a, b] (given they compare equal). With unstable sort, the result could also be [b, a].

If stability is necessary, use #sort! instead.

Raises ArgumentError if the comparison between any two elements returns nil.

Source
unstable_sort!

Sorts all elements in self based on the comparator in the given block, using an unstable sort algorithm.

slice = Slice[3, 1, 2]
# This is a reverse sort (forward sort would be `a <=> b`)
slice.unstable_sort! { |a, b| b <=> a }
slice # => Slice[3, 2, 1]

The block must implement a comparison between two elements a and b, where a < b outputs a negative value, a == b outputs 0, and a > b outputs a positive value. The comparison operator (Comparable#<=>) can be used for this.

The block's output type must be <= Int32?, but returning an actual nil value is an error.

This sort operation modifies self. See #unstable_sort(&block : T, T -> U) for a non-modifying option that allocates a new instance.

The sort mechanism is implemented as introsort. It does not guarantee stability between equally comparing elements. This offers higher performance but may be unexpected in some situations.

Stability means that two elements which compare equal (i.e. a <=> b == 0) keep their original relation. Stable sort guarantees that [a, b].sort! always results in [a, b] (given they compare equal). With unstable sort, the result could also be [b, a].

If stability is necessary, use #sort!(&block : T, T -> U) instead.

Raises ArgumentError if for any two elements the block returns nil.

Source
unstable_sort_by

Returns a new instance with all elements sorted by the output value of the block. The output values are compared via the comparison method #<=> (see Comparable#<=>), using an unstable sort algorithm.

a = Slice["apple", "pear", "fig"]
b = a.unstable_sort_by { |word| word.size }
b # => Slice["fig", "pear", "apple"]
a # => Slice["apple", "pear", "fig"]

If stability is necessary, use #sort_by(&block : T -> _) instead.

See Indexable::Mutable#unstable_sort!(&block : T -> _) for details on the sorting mechanism.

Raises ArgumentError if the comparison between any two comparison values returns nil.

Source
unstable_sort_by!

Modifies self by sorting all elements. The given block is called for each element, then the comparison method <=> is called on the object returned from the block to determine sort order.

a = Slice["apple", "pear", "fig"]
a.sort_by! { |word| word.size }
a # => Slice["fig", "pear", "apple"]

This method does not guarantee stability between equally sorting elements. Which results in a performance advantage over stable sort.

Source
update(index : Int, & : T -> _) : T

Yields the current element at the given index and updates the value at that index with the block's value. Returns the new value.

Raises IndexError if trying to set an element outside the container's range.

array = [1, 2, 3]
array.update(1) { |x| x * 2 } # => 4
array                         # => [1, 4, 3]
array.update(5) { |x| x * 2 } # raises IndexError

Raises if this slice is read-only.

Source

Macros

[](*args, read_only = false)

Creates a new Slice with the given args. The type of the slice will be the union of the type of the given args.

The slice is allocated on the heap.

slice = Slice[1, 'a']
slice[0]    # => 1
slice[1]    # => 'a'
slice.class # => Slice(Char | Int32)

If T is a Number then this is equivalent to Number.slice (numbers will be coerced to the type T)

  • Number.slice is a convenient alternative for designating a specific numerical item type.
Source