I read in Apple Docs:
"When you add elements to an array and that array begins to exceed its reserved capacity, the array allocates a larger region of memory and copies its elements into the new storage. The new storage is a multiple of the old storage’s size."
So, I opened the Playground and created some examples. The first example seems correct:
var array = [1, 2, 3, 4, 5]
array.capacity //5
array.append(contentsOf: [6, 7, 8, 9, 10])
array.capacity //10
array.append(11)
array.capacity //20
But I didn't understand the second example:
var array = [1, 2, 3, 4, 5]
array.capacity //5
array.append(contentsOf: [6, 7, 8, 9, 10, 11])
array.capacity //12
array.append(12)
array.capacity //12
Why is the capacity 12 in the second example? I didn't understand even reading the documentation and searching in Google.
I recommend you to check Rob and Matt's answers here
Even though there's a reserveCapacity function, it's not advised
from the docs:
The Array type’s append(:) and append(contentsOf:) methods take care of this detail for you, but reserveCapacity(:) allocates only as much space as you tell it to (padded to a round value), and no more. This avoids over-allocation, but can result in insertion not having amortized constant-time performance.
Related
I'd like to apply filter on my Flux based on a state calculated from previous values. However, it is recommended to avoid using state in operators according to the javadoc
Note that using state in the java.util.function / lambdas used within Flux operators should be avoided, as these may be shared between several Subscribers.
For example, Flux#distinct filters items that appears earlier. How can we implement our own version of distinct?
I have found an answer to my question. Flux#distinct can take a Supplier which provides initial state and a BiPredicate which performs "distinct" check, so we can store arbitrary state in the store and decide whether to keep each element.
Following code shows how to keep the first 3 elements of each mod2 group without changing the order.
// Get first 3 elements per mod 2.
Flux<Integer> first3PerMod2 =
Flux.fromIterable(ImmutableList.of(9, 3, 7, 4, 5, 10, 6, 8, 2, 1))
.distinct(
// Group by mod2
num -> num % 2,
// Counter to store how many elements have been processed for each group.
() -> new HashMap<Integer, Integer>(),
// Increment or set 1 to the counter,
// and return whether 3 elements are published.
(map, num) -> map.merge(num, 1, Integer::sum) <= 3,
// Clean up the state.
map -> map.clear());
StepVerifier.create(first3PerMod2).expectNext(9, 3, 7, 4, 10, 6).verifyComplete();
I just started a tutorial in Rust and I can't get my head around the limitation of tuple printing:
fn main() {
// Tuple definition
let short = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
let long = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
println!("{:?}", short); // Works fine
println!("{:?}", long); // ({integer}...{integer})` cannot be formatted using `:?` because it doesn't implement `std::fmt::Debug`
}
In my ignorant view the printing could be easily achieved by iterating over the entire tuple — this would allow displaying without size constraint. If the solution would be that simple it would be implemented, what am I missing here?
Printing tuples is currently implemented using a macro that only works up to 12 elements.
Functionality to statically iterate/manipulate tuples has been proposed, but has been postponed (see e.g. this RFC). There was some concerns about the implementation of these (e.g. you'd expect to be able to get the head & tail of a tuple, but there is actually no guarantee that a tuple will be stored in the same order as you specified, because the compiler is allowed to optimize for space, which means getting the tail wouldn't be a trivial operation).
As for why you need special support for that, consider the following tuple:
let mixed = (42, true, 3.14, "foo");
How you would iterate this tuple, given that all its elements have a different type? This can't simply be done using regular iterators and a for loop. You would need some new type-level syntax, which Rust is currently lacking.
Debug is only implemented on tuples up to 12 elements. This is why printing short works, but long fails.
If I unpack then pack an array:
arr = {1, 2, 3, 4, 5}
arr = table.pack(table.unpack(arr))
Will I guarantee that the resulting arr is the same as the initial arr?
In the documentation it states:
Note that the resulting table may not be a sequence.
What does this mean?
The documentation you cite is talking about nils as in
table.pack(1,nil,3).
Your table is a sequence and so table.unpack(arr) outputs no nils and table.pack(table.unpack(arr)) is a sequence.
However, table.pack(table.unpack(arr)) differs from the original arr because it contains a field n with value 5. This is the only difference.
I have a basic architecture based question. How does multi dimensional arrays layout in memory? Is this correct that data layout linearly in memory? Is so, is it correct that in row major order data store based on row orders (first row store, then second row ...) and in column major data stores based on columns?
Thanks
The representation of an array depends upon the programming language. Most languages (the C abortion and its progeny being notable exceptions) represent arrays using a descriptor. The descriptor specifies the number of dimensions the upper and lower bounds of each dimension, and where the data is located.
Usually, the all the data for the array is stored contiguously. Even when stored contiguously the ordering depends upon the language. In some languages [0, 0, 0] is stored next to [1, 0, 0] (Column Major—e.g. FORTRAN)). In others [0, 0, 0] is next to [0, 0, 1] (and [0, 0, 0] and [1, 0, 0] are apart—row major—e.g., Pascal). Some languages, such as Ada, leave the ordering up to the compiler implementation.
Each array is stored in sequence, naturally. It makes no sense to spread data all over the place.
Example in C:
int matrix[10][10];
matrix[9][1] = 1234;
printf("%d\n", matrix[9][1]); // prints 1234
printf("%d\n", ((int*)matrix)[9 * 10 + 1]); // prints 1234
Of course there is nothing enforcing you to organize data this way, if you want to make a mess you can do it.
For example, if instead of using an array of arrays you decide to dynamically allocate your matrix:
int **matrix;
matrix = malloc(10 * sizeof(int*));
for (int i = 0; i < 10; ++i)
matrix[i] = malloc(10 * sizeof(int));
The above example is most likely still stored in sequence, but certainly not in a contiguous manner, because there are 11 different memory blocks allocated and the memory manager is free to allocate them wherever it makes sense to it.
Part of my code is like this:
Load_name:addLoad({'incrementalnodalload', 7, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
the last part (I mean 1,2,...,10) can be extended as much as required (for example 1,2,...,1000).
Thus I want to replace this part with something like this:
Load_name:addLoad({'incrementalnodalload', 7, 1, inc_number})
inc_number = 1:1000
However, it does not work!
Any suggestion is highly appreciated!
Here is inc_number function that accepts two parameters and does what you need in this context:
function inc_number(f,t)
if f > t then return else return f,inc_number(f+1,t) end
end
Load_name:addLoad({'incrementalnodalload', 7, 1, inc_number(1,100)})
Note that it only works when the result of inc_number call is the last parameter in the list of parameters. Example:
print(table.concat({inc_number(1,10)}, ","))
-- prints: 1,2,3,4,5,6,7,8,9,10