In lua, array sub element - arrays

In Lua,
I want to select the parts of the array.
The below example selects from the second elements
a = { 1, 2, 3}
print(a)
b = {}
for i = 2, table.getn(a) do
table.insert(b, a[i])
end
print(b)
In python a[1:] works.
Does Lua have the similar syntax?

Lua does not have similar syntax. However, you can define your own function to easily wrap this logic up.
local function slice (tbl, s, e)
local pos, new = 1, {}
for i = s, e do
new[pos] = tbl[i]
pos = pos + 1
end
return new
end
local foo = { 1, 2, 3, 4, 5 }
local bar = slice(foo, 2, 4)
for index, value in ipairs(bar) do
print (index, value)
end
Note that this is a shallow copy of the elements in foo to bar.
Alternatively, in Lua 5.2 you could use table.pack and table.unpack.
local foo = { 1, 2, 3, 4, 5 }
local bar = table.pack(table.unpack(foo, 2, 4))
Although the manual has this to say:
table.pack (ยทยทยท)
Returns a new table with all parameters stored into keys 1, 2, etc. and with a field "n" with the total number of parameters. Note that the resulting table may not be a sequence.
While Lua 5.3 has table.move:
local foo = { 1, 2, 3, 4, 5 }
local bar = table.move(foo, 2, 4, 1, {})
And finally, most would probably opt to define some kind of OOP abstraction over this.
local list = {}
list.__index = list
function list.new (o)
return setmetatable(o or {}, list)
end
function list:append (v)
self[#self + 1] = v
end
function list:slice (i, j)
local ls = list.new()
for i = i or 1, j or #self do
ls:append(self[i])
end
return ls
end
local foo = list.new { 1, 2, 3, 4, 5 }
local bar = foo:slice(2, 4)

Related

Save previous bar values when using a loop in pine script

In pine script I'm calling a function that sums the previous bar value with an increment:
myFunction(myVar1) =>
var int myVar2 = 0
myVar2 := myVar1 + nz(myVar2[1],1)
The increment value is added using a loop that calls the function and the result is stored in an array:
myArray = array.new_int(0)
var int myVar1 = 1
myVar1 := 1
while myVar1 <= 3
array.push(myArray, myFunction(myVar1))
myVar1 += 1
The result in the first bar was expected. Since there is no previous bar the previous value is replaced by 1 nz(myVar2[1],1)
plot(myArray.get(myArray, 0))
plot(myArray.get(myArray, 1))
plot(myArray.get(myArray, 2))
Result: [2, 3, 4]
But in the second bar:
Result: [5, 6, 7]
My expected result: [3, 5, 7]
Since it runs the loop for the first bar first and then runs the loop again in the second bar it uses for myVar2[1] the last value 4 saved when running the last loop in the first bar.
How can the previous bar values be stored correctly when using a loop so that the expected results can be achieved:
First bar: [2, 3, 4]
Second bar: [3, 5, 7]
Third bar: [4, 7, 10]
Answer to your comment: You could save the current array in another array. That way, you always have access to the array values of the previous bar.
//#version=5
indicator("My Script", overlay=false)
var int myVar1 = na
var int[] myArray = array.new_int(3) // Current array
var int[] prevArray = array.new_int(3) // Previous array
myFunction(myVar1) =>
var int myVar2 = 0
myVar2 := myVar1 + nz(myVar2[1],1)
myVar1 := 1
prevArray := array.copy(myArray) // Save current array
array.clear(myArray) // Clear current array
while myVar1 <= 3
array.push(myArray, myFunction(myVar1))
myVar1 += 1
// Show previous array
plot(array.get(prevArray, 0), 'prevArray[0]')
plot(array.get(prevArray, 1), 'prevArray[1]')
plot(array.get(prevArray, 2), 'prevArray[2]')
// Show current array
plot(array.get(myArray, 0), 'myArray[0]')
plot(array.get(myArray, 1), 'myArray[1]')
plot(array.get(myArray, 2), 'myArray[2]')

How to rotate an array using array reversal technique?

I am trying to rotate an array from a particular position using array reversal method.
Input array: [1,2,3,4,5,6,7]
d = 3
Output array: [5,6,7,1,2,3,4]
To achieve this I thought of working on the array in three steps.
Step1: Reverse the array from starting position until d => [4,3,2,1,5,6,7]
Step2: Reverse the array from d till the end of the array => [4,3,2,1,7,6,5]
Step3: Reverse the complete array from Step2 => [5,6,7,1,2,3,4]
I haven't followed any functional programming pattern as I want to check the algorithm step by step.
val arr = Array[Int](1, 2, 3, 4, 5, 6, 7)
def reverseAlgo(brr: Array[Int], start: Int, end: Int): Unit = {
var temp = 0
for(i <- start until end/2) {
temp = brr(i)
brr(i) = brr(end-i-1)
brr(end-i-1) = temp
}
brr.foreach(println)
}
Step1 is working fine:
reverseAlgo(arr, 0, 3)
Output:
3
2
1
4
5
6
7
But Step2 is not producing the required output:
reverseAlgo(arr, 3, 7)
Output:
3
2
1
4
5
6
7
As you see, the output of the array should be: 3,2,1,7,6,5,4
Since the output from Step2 is incorrect, the final output is also wrong.
Step3:
reverseAlgo(arr, 0, arr.length)
Output:
7
6
5
4
1
2
3
Could anyone let me know what is the mistake I am doing here ?
Why not just something as simple as this?
import scala.collection.immutable.ArraySeq
import scala.reflect.ClassTag
def rotate[T : ClassTag](arr: ArraySeq[T])(pos: Int): ArraySeq[T] = {
val length = arr.length
ArraySeq.tabulate[T](n = length) { i =>
arr((i + 1 + pos) % length)
}
}
Which can be used like this:
rotate(arr = ArraySeq(1, 2, 3, 4, 5, 6, 7))(pos = 3)
// res: ArraySeq[Int] = ArraySeq(, 5, 6, 7, 1, 2, 3, 4)
You can see the code running here.
Your code will only work when the range starts at zero.
for(i <- start until end/2) {
temp = brr(i)
brr(i) = brr(end-i-1)
brr(end-i-1) = temp
}
Should be something like:
for(i <- 0 until (end-start)/2) {
temp = brr(start+i)
brr(start+i) = brr(end-i-1)
brr(end-i-1) = temp
}
With this change your code works.
Mutation is to be avoided but, if you must, recursion is still useful.
def reversePart[A](arr: Array[A], start: Int, end: Int): Unit = {
def loop(a:Int, b:Int): Unit =
if (a < b) {
val temp = arr(a)
arr(a) = arr(b)
arr(b) = temp
loop(a+1, b-1)
}
loop(start max 0, end min arr.length-1)
}
val test = Array(1, 2, 3, 4, 5, 6, 7)
reversePart(test, 0, 3) //Array(4, 3, 2, 1, 5, 6, 7)
reversePart(test, 4, 7) //Array(4, 3, 2, 1, 7, 6, 5)
reversePart(test, -1, 99) //Array(5, 6, 7, 1, 2, 3, 4)
I realize this doesn't directly answer your question, but for reference and for readers interested in a slightly different approach, one possibility is to implement this as a view.
In this example, Rotate implements the logic, while IndexedSeqViewRotate adds the rotate method as an extension to any IndexedSeqView as long as it's in scope.
In the tests, I materialized the views into Vectors to take advantage of the equality, but of course you can materialize them into an Array as well.
import scala.collection.IndexedSeqView
import scala.collection.IndexedSeqView.SomeIndexedSeqOps
final class Rotate[A](underlying: SomeIndexedSeqOps[A], n: Int) extends IndexedSeqView[A] {
#inline private def rotateIndex(i: Int): Int = ((i - n) % length + length) % length
override def apply(i: Int): A = underlying(rotateIndex(i))
override lazy val length: Int = underlying.length
}
final implicit class IndexedSeqViewRotate[A](val underlying: IndexedSeqView[A]) extends AnyVal {
def rotate(n: Int): IndexedSeqView[A] = new Rotate(underlying, n)
}
assert(Array().view.rotate(7).to(Vector) == Vector.empty)
assert(Array(1,2,3,4,5,6,7).view.rotate(7).to(Vector) == Vector(1,2,3,4,5,6,7))
assert(Array(1,2,3,4,5,6,7).view.rotate(0).to(Vector) == Vector(1,2,3,4,5,6,7))
assert(Array(1,2,3,4,5,6,7).view.rotate(1).to(Vector) == Vector(7,1,2,3,4,5,6))
assert(Array(1,2,3,4,5,6,7).view.rotate(3).to(Vector) == Vector(5,6,7,1,2,3,4))
assert(Array(1,2,3,4,5,6,7).view.rotate(-1).to(Vector) == Vector(2,3,4,5,6,7,1))
You can play around with this code here on Scastie.

Perl - function with two array arguments

I have troubles using a function in Perl.
My function has 2 arguments which are arrays :
sub get_coordinate {
my (#array_col, #array_lin) = (#_);
do some stuff
}
I call it this way :
$index_col = int(rand(10));
$index_lin = int(rand(10));
#array_col = (0,0,0,0,0,0,0,0,0,0);
#array_lin = (0,0,0,0,0,0,0,0,0,0);
$array_col[$index_col] = 1;
$array_lin[$index_lin] = 1;
get_coordinate(#array_col, #array_lin);
My problem is that I get the error message : Use of uninitialized value within #array_lin in numeric eq (==) at
switch.pl line 82 (#1)
(W uninitialized) An undefined value was used as if it were already
defined. It was interpreted as a "" or a 0, but maybe it was a mistake.
To suppress this warning assign a defined value to your variables.
I don't understand why #array_col is initialized an not #array_lin.
When I print #array_col and #array_lin inside the function this way :
print "#array_col\n#array_lin\n";
I get : 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0
Any idea ?
Thx,
SLP
In Perl, all lists are flat. These two lists are equivalent.
( 1, 2, ( 3, 4, ( 5 ), (6, 7), 8), (), )
( 1, 2, 3, 4, 5, 6, 7, 8 )
The same thing also happens when take several arrays and stick them in a list.
my #foo = (1, 2, 3);
my #bar = (4, 5, 6);
my #new = (#foo, #bar); # 1, 2, 3, 4, 5, 6
When you pass things to a function, those things get turned into a list of arguments. Therefore, the arrays will both end up in one list, like #foo and #bar above.
frobnicate(#foo, #bar);
When you assign something in list context, the entire list will be assigned left to right. For scalars in the list on the left-hand-side this means they will get their values. But as soon as there is an array, this will be greedy. It will suck up all the remaining values.
my ($one, $two, #rest, $will_be_undef) = (1, 2, 3, 4, 5, 6);
The values will be assigned like this:
$one = 1;
$two = 2;
#rest = ( 3, 4, 5, 6 );
$will_be_undef = undef;
What you need to do to pass two arrays is to take references, and dereference them in our function.
frobnicate( \#foo, \#bar );
sub frobnicate {
my ($first_array, $second_array) = #_;
my #foo = #{ $first_array };
my #bar = #{ $second_array };
...
}
Assigning to several arrays (or hashes) doesn't do what you think:
my (#array1, #array2) = ...
The first array gets all the elements. How should it know where to stop?
You can use array references instead:
sub get_coordinate {
my ($arr1, $arr2) = #_;
my #arr1 = #$arr1;
my #arr2 = #$arr2;
...
}
get_coordinate(\#array1, \#array2);

Rotate kotlin array

Assume that I have an array like 1 2 3 4 5, I want to rotate it to the left by n and get a new one.
For example the 2 rotation of the above array will result in 3 4 5 1 2. I didn't found any extension function to do that.
You can use built-in java Collections.rotate method, but you need to convert your array to list firstly:
val arr = intArrayOf(1, 2, 3, 4, 5)
val list = arr.toList()
Collections.rotate(list, -2)
println(list.toIntArray().joinToString())
Outputs
3, 4, 5, 1, 2
I interpret "get a new one" to mean that the extension function should return a new array instance, like so (boundary checks omitted, sliceArray is an stdlib function) :
fun <T> Array<T>.rotate(n: Int) =
let { sliceArray(n until size) + sliceArray(0 until n) }
Example
arrayOf(1, 2, 3, 4, 5).rotate(1)
.also { println(it.joinToString()) } // 2, 3, 4, 5, 1
Another extension function, by slicing the array in 2 parts left and right and reassembling it to right + left:
fun <T> Array<T>.leftShift(d: Int) {
val n = d % this.size // just in case
if (n == 0) return // no need to shift
val left = this.copyOfRange(0, n)
val right = this.copyOfRange(n, this.size)
System.arraycopy(right, 0, this, 0, right.size)
System.arraycopy(left, 0, this, right.size, left.size)
}
so this:
val a = arrayOf(1, 2, 3, 4, 5, 6, 7)
a.leftShift(2)
a.forEach { print(" " + it) }
will print
3 4 5 6 7 1 2
Simple solution:
fun <T> Array<T>.rotateLeft(n: Int) = drop(n) + take(n)
fun <T> Array<T>.rotateRight(n: Int) = takeLast(n) + dropLast(n)
The limitation is that n must be less than or equal to the length of the array.
Alternatively, you can use Collections.rotate(...) as follows.
import java.util.Collections
fun <T> Array<T>.rotate(distance: Int) =
toList().also { // toList() is a deep copy to avoid changing the original array.
Collections.rotate(it, distance)
}
fun main() {
val xs = arrayOf(1, 2, 3, 4, 5)
val ys = xs.rotate(-2)
xs.forEach { print("$it ") } // 1 2 3 4 5
println(ys) // [3, 4, 5, 1, 2]
}
For the record, you can use the regular Array constructor to build a new array:
inline fun <reified T> Array<T>.rotate(n: Int) = Array(size) { this[(it + n) % size] }
The element at index it in the source array is copied in the destination array at the new index (it + n) % size to perform the rotation.
It is a bit slower than copying the array by chunks.

Compare Array Uniquely - Ruby [duplicate]

Let's say I am trying to remove elements from array a = [1,1,1,2,2,3]. If I perform the following:
b = a - [1,3]
Then I will get:
b = [2,2]
However, I want the result to be
b = [1,1,2,2]
i.e. I only remove one instance of each element in the subtracted vector not all cases. Is there a simple way in Ruby to do this?
You may do:
a= [1,1,1,2,2,3]
delete_list = [1,3]
delete_list.each do |del|
a.delete_at(a.index(del))
end
result : [1, 1, 2, 2]
[1,3].inject([1,1,1,2,2,3]) do |memo,element|
memo.tap do |memo|
i = memo.find_index(e)
memo.delete_at(i) if i
end
end
Not very simple but:
a = [1,1,1,2,2,3]
b = a.group_by {|n| n}.each {|k,v| v.pop [1,3].count(k)}.values.flatten
=> [1, 1, 2, 2]
Also handles the case for multiples in the 'subtrahend':
a = [1,1,1,2,2,3]
b = a.group_by {|n| n}.each {|k,v| v.pop [1,1,3].count(k)}.values.flatten
=> [1, 2, 2]
EDIT: this is more an enhancement combining Norm212 and my answer to make a "functional" solution.
b = [1,1,3].each.with_object( a ) { |del| a.delete_at( a.index( del ) ) }
Put it in a lambda if needed:
subtract = lambda do |minuend, subtrahend|
subtrahend.each.with_object( minuend ) { |del| minuend.delete_at( minuend.index( del ) ) }
end
then:
subtract.call a, [1,1,3]
A simple solution I frequently use:
arr = ['remove me',3,4,2,45]
arr[1..-1]
=> [3,4,2,45]
a = [1,1,1,2,2,3]
a.slice!(0) # remove first index
a.slice!(-1) # remove last index
# a = [1,1,2,2] as desired
For speed, I would do the following, which requires only one pass through each of the two arrays. This method preserves order. I will first present code that does not mutate the original array, then show how it can be easily modified to mutate.
arr = [1,1,1,2,2,3,1]
removals = [1,3,1]
h = removals.group_by(&:itself).transform_values(&:size)
#=> {1=>2, 3=>1}
arr.each_with_object([]) { |n,a|
h.key?(n) && h[n] > 0 ? (h[n] -= 1) : a << n }
#=> [1, 2, 2, 1]
arr
#=> [1, 1, 1, 2, 2, 3, 1]
To mutate arr write:
h = removals.group_by(&:itself).transform_values(&:count)
arr.replace(arr.each_with_object([]) { |n,a|
h.key?(n) && h[n] > 0 ? (h[n] -= 1) : a << n })
#=> [1, 2, 2, 1]
arr
#=> [1, 2, 2, 1]
This uses the 21st century method Hash#transform_values (new in MRI v2.4), but one could instead write:
h = Hash[removals.group_by(&:itself).map { |k,v| [k,v.size] }]
or
h = removals.each_with_object(Hash.new(0)) { | n,h| h[n] += 1 }

Resources