Listbox code from As Variant to As Long - listbox

I've learned that the As Long is much better than As Variant when it come to improving macro speed.
Dim data1() As Variant
data1 = Array("a", "b", "c", "d", "e")
Sheet1.ListBox1.List = data1
When I replace with As Long, my code doesn't work any more.

Your array doesn't contain Longs, it contains Strings. Try Dim data1() As String. (Don't worry - it's probably still faster than As Variant.)

While using explicit types is usually (almost always) better. This case is an exception because the List property of the ListBox is a Variant array anyway, so assigning a String or Long array to it causes an implicit type cast, so isn't any faster (and may even be slower).
What may make the difference is how you are loading data into the array before assigning it to the ListBox. If thats more efficient use explicit typed arrays then fine, use it.
BTW
Dim data1() as long
data1 = Array(1, 2, 3, 4, 5)
doesn't work because Array(...) returns a Varaint array which can't be assigned to an explicit typed array.

Related

Converting a slice to an array

I have a slice that I have guaranteed (in runtime) that its length is at least 8. I want to convert that slice to an array because I need to use std.mem.bytesAsValue() in order to create an f64 from raw bytes (for context, I'm implementing a binary serialization format).
I solved it like this, but I'd like to know if there is a better syntax for achieving the same goal:
var array: [8]u8 = undefined;
array[0] = slice[0];
array[1] = slice[1];
array[2] = slice[2];
array[3] = slice[3];
array[4] = slice[4];
array[5] = slice[5];
array[6] = slice[6];
array[7] = slice[7];
Given your goal, if alignment works out, you could just cast the slice pointer to a pointer to a f64: #ptrCast(*f64, slice.ptr). This saves you from even having to copy anything, in case you don't need to do that at all.
Note that bytesAsValues is a stdlib function that uses compiler builtins, if the signature doesn't match your needs, you can just skip it and use directly the builtins, like I mentioned above. Don't be afraid to read the stdlib source code.
Here's a godbolt link with some examples on how to do the conversion in-place (by casting the pointer) and by copying everything immediately as a float: https://zig.godbolt.org/z/3Y9o5zvfe
you can do this by std.mem.copy
var array = slice[0..8].*;
or using std.mem.copy
std.mem.copy(u8, &array, slice[0..2]);
while i think you can just need to put slice[0..8] as argument instead creating a variable

Dart - When To Use Collection-For-In vs .Map() on Collections

Both the collection-for-in operation and .map() method can return some manipulation of elements from a previous collection. Is there ever any reason to prefer using one over the other?
var myList = [1,2,3];
var alteredList1 = [for(int i in myList) i + 2]; //[3,4,5]
var alteredList2 = myList.map((e) => e + 2).toList(); //[3,4,5]
Use whichever is easier and more readable.
That's a deliberately vague answer, because it depends on what you are doing.
Any time you have something ending in .toList() I'd at least consider making it into a list literal. If the body of the map or where is simple, you can usually rewrite it directly to a list literal using for/in (plus if for where).
And then, sometimes it gets complicated, you need to use the same variable twice, or the map computation uses a while loop, or something else doesn't just fit into the list literal syntax.
Then you can either keep the helper function and do [for (var e in something) helperFunction(e)] or just do something.map((e) { body of helper function }).toList(). In many cases the latter is then more readable.
So, consider using a list literal if your iterable code ends in toList, but if the literal gets too convoluted, don't feel bad about using the .map(...).toList() approach.
Readability is all that really matters.
Not an expert but personally I prefer the first method. Some reasons:
You can include other elements (independent from the for loop) in the same list:
var a = [1, 2, 3];
bool include5 = true;
var b = [
1,
for (var i in a) i + 1,
if (include5) 5,
];
print(b); // [1, 2, 3, 4, 5]
Sometimes when mapping models to a list of Widgets the .map().toList() method will produce a List<dynamic>, implicit casting won't work. When you come across such an error just avoid the second method.

How do you remove (or 'unstore') an element from a Z3 array?

It is easy to store an element into a Z3 array. For example:
ArrayExpr mem = ctx.MkArrayConst("mem", ctx.MkBitVecSort(nBits), ctx.MkBitVecSort(nBits));
BitVecExpr addr = ctx.MkBV(10, nBits);
BitVecExpr value = ctx.MkBV(20, nBits);
mem = ctx.MkStore(mem, addr, value);
But how do you change or remove an element from such an array?
The method MkSetDel with signature "ArrayExpr MkSetDel(ArrayExpr set, Expr element)" seem to suggest that it can be (mis)used for that purpose; but sadly, it only accepts sets.
If there exists a method to iterate over the asserted elements in the array, I could populate a new array and skip the one I am changing or deleting. But I can not find such a method.
I guess I missing something.
Z3 essentially supports a first-order logic with theory extensions such as array, and consequently only supports values, which are by definition immutable. Arrays are also values, and cannot be changed. Updating an array (at some index) yields a new array (an array value) whose elements are equal to those from the original array except at the index that your change affected.
See the Z3 tutorial on array for more details about arrays and the store and select operations.
By the way, what do you mean with "remove an element from an array"? Would that shorten the array by cutting out an element? That isn't even supported in most programming languages (where arrays are consecutive memory locations). Would it shift all subsequent elements to the front?

Is there a difference between slicing and an explicit reborrow when converting Strings to &strs?

Are the following two examples equivalent?
Example 1:
let x = String::new();
let y = &x[..];
Example 2:
let x = String::new();
let y = &*x;
Is one more efficient than the other or are they basically the same?
In the case of String and Vec, they do the same thing. In general, however, they aren't quite equivalent.
First, you have to understand Deref. This trait is implemented in cases where a type is logically "wrapping" some lower-level, simpler value. For example, all of the "smart pointer" types (Box, Rc, Arc) implement Deref to give you access to their contents.
It is also implemented for String and Vec: String "derefs" to the simpler str, Vec<T> derefs to the simpler [T].
Writing *s is just manually invoking Deref::deref to turn s into its "simpler form". It is almost always written &*s, however: although the Deref::deref signature says it returns a borrowed pointer (&Target), the compiler inserts a second automatic deref. This is so that, for example, { let x = Box::new(42i32); *x } results in an i32 rather than a &i32.
So &*s is really just shorthand for Deref::deref(&s).
s[..] is syntactic sugar for s.index(RangeFull), implemented by the Index trait. This means to slice the "whole range" of the thing being indexed; for both String and Vec, this gives you a slice of the entire contents. Again, the result is technically a borrowed pointer, but Rust auto-derefs this one as well, so it's also almost always written &s[..].
So what's the difference? Hold that thought; let's talk about Deref chaining.
To take a specific example, because you can view a String as a str, it would be really helpful to have all the methods available on strs automatically available on Strings as well. Rather than inheritance, Rust does this by Deref chaining.
The way it works is that when you ask for a particular method on a value, Rust first looks at the methods defined for that specific type. Let's say it doesn't find the method you asked for; before giving up, Rust will check for a Deref implementation. If it finds one, it invokes it and then tries again.
This means that when you call s.chars() where s is a String, what's actually happening is that you're calling s.deref().chars(), because String doesn't have a method called chars, but str does (scroll up to see that String only gets this method because it implements Deref<Target=str>).
Getting back to the original question, the difference between &*s and &s[..] is in what happens when s is not just String or Vec<T>. Let's take a few examples:
s: String; &*s: &str, &s[..]: &str.
s: &String: &*s: &String, &s[..]: &str.
s: Box<String>: &*s: &String, &s[..]: &str.
s: Box<Rc<&String>>: &*s: &Rc<&String>, &s[..]: &str.
&*s only ever peels away one layer of indirection. &s[..] peels away all of them. This is because none of Box, Rc, &, etc. implement the Index trait, so Deref chaining causes the call to s.index(RangeFull) to chain through all those intermediate layers.
Which one should you use? Whichever you want. Use &*s (or &**s, or &***s) if you want to control exactly how many layers of indirection you want to strip off. Use &s[..] if you want to strip them all off and just get at the innermost representation of the value.
Or, you can do what I do and use &*s because it reads left-to-right, whereas &s[..] reads left-to-right-to-left-again and that annoys me. :)
Addendum
There's the related concept of Deref coercions.
There's also DerefMut and IndexMut which do all of the above, but for &mut instead of &.
They are completely the same for String and Vec.
The [..] syntax results in a call to Index<RangeFull>::index() and it's not just sugar for [0..collection.len()]. The latter would introduce the cost of bound checking. Gladly this is not the case in Rust so they both are equally fast.
Relevant code:
index of String
deref of String
index of Vec (just returns self which triggers the deref coercion thus executes exactly the same code as just deref)
deref of Vec

Swift multidimensional array

I'm working on a piece of code that use generics. This is an example of what I'm trying to achieve :
var strings: Array<Array<String>> = [["1", "2", "3"], ["4", "5", "6"]]
var array: Array<Array<AnyObject>> = strings
But the compiler says "'String' is not identical to 'AnyObject'".
I have no idea why the compiler complains and how to achieve what I need.
I already tried casting it like this :
var array: Array<Array<AnyObject>> = strings as Array<Array<AnyObject>>
Without any success.
Do you guys have any idea ?
Thanks.
That doesn't work because, as the compiler says, AnyObject is not String, although you can cast AnyObject to String and vice versa.
It doesn't even work using different value types that may seem "compatible":
var array1: Array<Array<UInt>> = []
var array2: Array<Array<Int>> = array1
The only way to do what you need is to write a converter that given an array containing object of type String returns an array of AnyObject.
The reason is that even if 2 data types are compatible, they do not use the same amount of memory and can have different data members and initialization constraints.
Taking into account that arrays are value types, the assignment is not done by reference - instead a copy of the array is created and assigned to the destination variable. If the underlying data type is the same for left and right side of the assignment, each item in the array can just be copied byte by byte to create a copy of it. If the left and right side have different types, that is not possible because most likely they use memory in a different way (i.e. they may have different data members), so in that case the object should be instantiated via an initializer, but which one and using which parameters?

Resources