How do/ can I print an arrays contents into a textView in Android Studios Kotlin - arrays

lets say I'm making a simple dnd dice roller (cause I am), I get results and I turn it into an array.
Now I want to print the results of the array into a textView that would say:
randNumResultsDisplay.text = "Rolled " then it would spit out all results in the array, in order that they were put in.

I'm not entirely sure where you are stuck here, but if you want to convert an array into a String, one option is to use the java.utils.Arrays class:
val myArray = arrayOf(1, 2, 3)
val contents = Arrays.toString(myArray)
println(contents) // prints "[1, 2, 3]"
So to inject that in your text view as you suggested:
randNumResultsDisplay.text = "Rolled ${Arrays.toString(yourValuesArray)}"
That being said, you would get it for free if you used List instead of Array (which is very much advised):
randNumResultsDisplay.text = "Rolled $yourList"
Another option as pointed out in the comments is the joinToString method, which works on both arrays and lists and allows you to customize the formatting:
println("Rolled: ${myArray.joinToString()}")
// Rolled 1, 2, 3
println("Rolled: ${myArray.joinToString(prefix = "[", postfix = "]")}")
// Rolled [1, 2, 3]
println("Rolled: ${myArray.joinToString(separator = "|")}")
// Rolled 1|2|3

Related

Add Array in single line to new file and load Array in single line

Hey I'm writing a simple game, where I want to save progress and load it at another point.
One one the elements to save is an array. I want to save this array in one single line as an array and also load it again as an array, but it only takes the first element and the following elements overwrite further content
Example (wrong) - Save Data
player_1 = "name"
array = [1, 2, 3]
count = 1000
File.open("game.txt", "w+") do |file|
file.puts player_1
file.puts array
file.puts count
end
Example (wrong) - Load Data
file_data = File.open("game.txt").readlines.map(&:chomp)
player_1 = file_data[0]
array = file_data[1]
count = file_data[2]
OUTPUT: TEXTFILE
name
1
2
3
1000
So I converted the array to a string and write it in text-file (it works but seems inconvenient)
to save the array
file.puts double_checker.to_s
# Output: String
"[1, 2, 3]"
to load the array (load string from text file, delete special chars, convert it back to array, convert elements to integers)
# Converts String back to Array, digits convert to Integers
double_checker = double_checker.delete(" []").split(",").map { |s| s.to_i }
# Output: Array
[1, 2, 3]
Now my question: Is there a way to store the array directly into to text file (in one line) and read it the same way, so I can store the array straight into a variable?
Or is it only possible to store Strings into a text file?
I'm trying to figure out how I can use write/read to save and load files for example a game progress.
One option would is to use Marshal::dump and Marshal::load.
player_1 = "name"
array = [1, 2, 3]
count = 1000
File.open("game.txt", 'wb') do |f|
f.write(Marshal.dump([player_1, array, count]))
end
#=> 28
player_1, array, count = Marshal.load(File.binread("game.txt"))
#=> ["name", [1, 2, 3], 1000]
Note that it is not guaranteed that an object serialized using dump with one version of Ruby will be readable with load with a later version of Ruby. On the other hand, Marshal can be used to serialize a wide range of Ruby objects.
"The marshaling library converts collections of Ruby objects into a byte stream", which is why Marshal's serialized objects should be written to and read from binary files.
Another option is to use JSON#generate and JSON#parse.
require 'json'
File.write("game.txt", JSON.generate([player_1, array, count]))
#=> 21
player_1, array, count = JSON.parse(File.read("game.txt"))
#=> ["name", [1, 2, 3], 1000]
One can alternatively use JSON::Ext::Generator::GeneratorMethods::Array#to_json to serialize the array:
player_1, array, count].to_json
#=> "[\"name\",[1,2,3],1000]"

How to collapse a multi-dimensional array of hashes in Ruby?

Background:
Hey all, I am experimenting with external APIs and am trying to pull in all of the followers of a User from a site and apply some sorting.
I have refactored a lot of the code, HOWEVER, there is one part that is giving me a really tough time. I am convinced there is an easier way to implement this than what I have included and would be really grateful on any tips to do this in a much more eloquent way.
My goal is simple. I want to collapse an array of arrays of hashes (I hope that is the correct way to explain it) into one array of hashes.
Problem Description:
I have an array named f_collectionswhich has 5 elements. Each element is an array of size 200. Each sub-element of these arrays is a hash of about 10 key-value pairs. My best representation of this is as follows:
f_collections = [ collection1, collection2, ..., collection5 ]
collection1 = [ hash1, hash2, ..., hash200]
hash1 = { user_id: 1, user_name: "bob", ...}
I am trying to collapse this multi-dimensional array into one array of hashes. Since there are five collection arrays, this means the results array would have 1000 elements - all of which would be hashes.
followers = [hash1, hash2, ..., hash1000]
Code (i.e. my attempt which I do not want to keep):
I have gotten this to work with a very ugly piece of code (see below), with nested if statements, blocks, for loops, etc... This thing is a nightmare to read and I have tried my hardest to research ways to do this in a simpler way, I just cannot figure out how. I have tried flatten but it doesn't seem to work.
I am mostly just including this code to show I have tried very hard to solve this problem, and while yes I solved it, there must be a better way!
Note: I have simplified some variables to integers in the code below to make it more readable.
for n in 1..5 do
if n < 5
(0..199).each do |j|
if n == 1
nj = j
else
nj = (n - 1) * 200 + j
end
#followers[nj] = #f_collections[n-1].collection[j]
end
else
(0..199).each do |jj|
njj = (4) * 200 + jj
#followers[njj] = #f_collections[n-1].collection[jj]
end
end
end
Oh... so It is not an array objects that hold collections of hashes. Kind of. Lets give it another try:
flat = f_collection.map do |col|
col.collection
end.flatten
which can be shortened (and is more performant) to:
flat = f_collection.flat_map do |col|
col.collection
end
This works because the items in the f_collection array are objects that have a collection attribute, which in turn is an array.
So it is "array of things that have an array that contains hashes"
Old Answer follows below. I leave it here for documentation purpose. It was based on the assumption that the data structure is an array of array of hashes.
Just use #flatten (or #flatten! if you want this to be "inline")
flat = f_collections.flatten
Example
sub1 = [{a: 1}, {a: 2}]
sub2 = [{a: 3}, {a: 4}]
collection = [sub1, sub2]
flat = collection.flatten # returns a new collection
puts flat #> [{:a=>1}, {:a=>2}, {:a=>3}, {:a=>4}]
# or use the "inplace"/"destructive" version
collection.flatten! # modifies existing collection
puts collection #> [{:a=>1}, {:a=>2}, {:a=>3}, {:a=>4}]
Some recommendations for your existing code:
Do not use for n in 1..5, use Ruby-Style enumeration:
["some", "values"].each do |value|
puts value
end
Like this you do not need to hardcode the length (5) of the array (did not realize you removed the variables that specify these magic numbers). If you you want to detect the last iteration you can use each_with_index:
a = ["some", "home", "rome"]
a.each_with_index do |value, index|
if index == a.length - 1
puts "Last value is #{value}"
else
puts "Values before last: #{value}"
end
end
While #flatten will solve your problem you might want to see how DIY-solution could look like:
def flatten_recursive(collection, target = [])
collection.each do |item|
if item.is_a?(Array)
flatten_recursive(item, target)
else
target << item
end
end
target
end
Or an iterative solution (that is limited to two levels):
def flatten_iterative(collection)
target = []
collection.each do |sub|
sub.each do |item|
target << item
end
end
target
end

Delete first element of List in Scala

I am trying to use a recursive function to go through each element in a List[Char], to check the number of occurrences of an element. I know there are easier ways and possibly even functions to do this, but would there be any way to delete just the first position of a List?
i tried using drop, and even used the following snipping but it did nothing, where test is the name of the list:
def delete(i: Int) = test.take(i) ++ test.drop((i+1));
I am trying to avoid using ListBuffer, and tried converting to Array but again to no success.
Your function is almost fine deleting item at i-th position, I would just add 'test' list as parameter to it:
scala> def delete[A](test:List[A])(i: Int) = test.take(i) ++ test.drop((i+1))
delete: [A](test: List[A])(i: Int)List[A]
scala> delete((1 to 10).toList)(3)
res0: List[Int] = List(1, 2, 3, 5, 6, 7, 8, 9, 10)
I think you trying to make some effect on 'test' using function delete but List is immutable, function delete will not produce side effect, it just returns new List

AS3 Splice(:ed) and wants to "re index"?

Ok, so I have a array like this.
myArray:Array []
myArray.push(Object) // x 4.
I have 4 objects in my array. Then I splice the second one. Leaving me with a array that looks like this. 1,3,4. Now... I would like to have this array look like this: 1,2,3. I Would like the 3 & 4 to simple switch place to one less from their own postion.
I know it's possible, I had a friend do it for me some years ago. How do I do this?
i think you are failing when using splice. splice and slice is different methods for array slice not changes the original array but returns new array with sliced gap
example
var arr:Array = ["Cat","Dog", "Mouse", "Cow"];
trace(arr.slice(1,3));// output : Dog,Mouse
trace(arr.slice(2));//output: Mouse,Cow
trace(arr) //output: Cat,Dog,Mouse,Cow
so when you call arr[3] you are getting Cow but your array didnt change at all
splice modifies your original array
var arr:Array = ["Cat","Dog", "Mouse", "Cow"];
arr.splice(1,1); // output: 0->Cat,1->Mouse,2->Cow
I would like to have this array look like this: 1,2,3
So...just pop() the last element:
myArray:Array = [1, 2, 3, 4];
myArray.pop();
trace(myArray); // Prints: 1,2,3
I Would like the 3 & 4 to simple switch place to one less from their own postion.
Umm...that's exactly what deleting the second element already did...
If the end result you want is that the second element be placed at the end, that is:
Before: [1, 2, 3, 4] --> After [1, 3, 4, 2]
Then you can do that in two steps:
var spliced = myArray.splice(1, 1); // Remove the second element and return it
myArray.push(spliced); // Push it to the end of the array
Technically you could do this in one step, since the splice will happen first:
myArray.push(myArray.splice(1, 1));
I ran your pseudo code ->
Here is the result:
[object Cat],[object Mouse],[object Cow]
There is no index when tracing.. another point, I some code
trace(arr[0] , arr[1], arr[2]);
And I still get
[object Cat],[object Mouse],[object Cow]
The indexes are fine automatically in AS3.
package regression
{
import flash.display.Sprite;
/**
* ...
* #author Arthur Wulf White
*/
public class Check_array_index_test_1 extends Sprite
{
public function Check_array_index_test_1()
{
var arr: Array = new Array();
arr.push(new Cat, new Dog, new Mouse, new Cow);
trace(arr);
arr.splice(1, 1);
trace(arr);
trace(arr[0] , arr[1], arr[2]);
}
}
}
class Cat { }
class Dog { }
class Mouse { }
class Cow {}

Python looping: idiomatically comparing successive items in a list

I need to loop over a list of objects, comparing them like this: 0 vs. 1, 1 vs. 2, 2 vs. 3, etc. (I'm using pysvn to extract a list of diffs.) I wound up just looping over an index, but I keep wondering if there's some way to do it which is more closely idiomatic. It's Python; shouldn't I be using iterators in some clever way? Simply looping over the index seems pretty clear, but I wonder if there's a more expressive or concise way to do it.
for revindex in xrange(len(dm_revisions) - 1):
summary = \
svn.diff_summarize(svn_path,
revision1=dm_revisions[revindex],
revision2 = dm_revisions[revindex+1])
This is called a sliding window. There's an example in the itertools documentation that does it. Here's the code:
from itertools import islice
def window(seq, n=2):
"Returns a sliding window (of width n) over data from the iterable"
" s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ... "
it = iter(seq)
result = tuple(islice(it, n))
if len(result) == n:
yield result
for elem in it:
result = result[1:] + (elem,)
yield result
What that, you can say this:
for r1, r2 in window(dm_revisions):
summary = svn.diff_summarize(svn_path, revision1=r1, revision2=r2)
Of course you only care about the case where n=2, so you can get away with something much simpler:
def adjacent_pairs(seq):
it = iter(seq)
a = it.next()
for b in it:
yield a, b
a = b
for r1, r2 in adjacent_pairs(dm_revisions):
summary = svn.diff_summarize(svn_path, revision1=r1, revision2=r2)
I'd probably do:
import itertools
for rev1, rev2 in zip(dm_revisions, itertools.islice(dm_revisions, 1, None)):
summary = svn.diff_sumeraize(svn_python, revision1=rev, revision2=rev2)
Something similarly cleverer and not touching the iterators themselves could probably be done using
So many complex solutions posted, why not keep it simple?
myList = range(5)
for idx, item1 in enumerate(myList[:-1]):
item2 = L[idx + 1]
print item1, item2
>>>
0 1
1 2
2 3
3 4
Store the previous value in a variable. Initialize the variable with a value you're not likely to find in the sequence you're handling, so you can know if you're at the first element. Compare the old value to the current value.
Reduce can be used for this purpose, if you take care to leave a copy of the current item in the result of the reducing function.
def diff_summarize(revisionList, nextRevision):
'''helper function (adaptor) for using svn.diff_summarize with reduce'''
if revisionList:
# remove the previously tacked on item
r1 = revisionList.pop()
revisionList.append(svn.diff_summarize(
svn_path, revision1=r1, revision2=nextRevision))
# tack the current item onto the end of the list for use in next iteration
revisionList.append(nextRevision)
return revisionList
summaries = reduce(diff_summarize, dm_revisions, [])
EDIT: Yes, but nobody said the result of the function in reduce has to be scalar. I changed my example to use a list. Basically, the last element is allways the previous revision (except on first pass), with all preceding elements being the results of the svn.diff_summarize call. This way, you get a list of results as your final output...
EDIT2: Yep, the code really was broken. I have here a workable dummy:
>>> def compare(lst, nxt):
... if lst:
... prev = lst.pop()
... lst.append((prev, nxt))
... lst.append(nxt)
... return lst
...
>>> reduce(compare, "abcdefg", [])
[('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'e'), ('e', 'f'), ('f', 'g'), 'g']
This was tested in the shell, as you can see. You will want to replace (prev, nxt) in the lst.append call of compare to actually append the summary of the call to svn.diff_summarize.
>>> help(reduce)
Help on built-in function reduce in module __builtin__:
reduce(...)
reduce(function, sequence[, initial]) -> value
Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.

Resources