[I've read the Lua manual, but it did not provide solid answers.]
Let's say I have a Lua Table, acting as an indexed array:
local myArray = {};
myArray[1] = "Foo";
myArray[2] = "Bar";
How do I best dispose of this Table? Do I just set myArray to nil? Or do I have to iterate through array and set each indexed element to nil?
Similarly, let's say I have I have a Lua Table, acting as a dictionary:
local myDictionary = {};
myDictionary["key1"] = "Foo";
myDictionary["key2"] = "Bar";
Can I just set 'myDictionary' to nil, or do I have to iterate through?
Lastly, what do I do, memory-management wise, where I have nested Tables? e.g.
local myNestedCollection = {};
myNestedCollection[1] = {1, 2, 3};
myNestedCollection[2] = {4, 5, 6};
Do I need to iterate through each of these sub-tables, setting them to nil? Thanks for any help.
It should be sufficient just to set the local variable to nil; there's no need to iterate through all of the keys and set them to nil to. According to this page, Lua uses a mark-and-sweep garbage collection algorithm. As soon as you set your local variable to nil, the keys in its table become unreachable, so they will be collected by the garbage collector on the next collection. Similarly, if those objects are also tables, their keys will also become unreachable, so they too will be collected.
In most GC an object will be collected when there are no references to it. Setting the top of your reference chain to nil removes a reference to the children. If that was the only reference then the children will be collected.
Related
I have the following scenario:
# Keeps track of all `HomeMadeObject` objects
obj_list = []
# A 2-dimensional matrix of either `nil` or `HomeMadeObject` elements
matrix = ...
# I then add an object like so.
obj = HomeMadeObject.new
matrix[y][x] = obj
obj_list.push(obj)
# Later on, I need to remove 'that same object' from the `matrix`.
matrix[y][x] = nil
When I set matrix[y][x] to nil, this will also affect the same object in the obj_list, making it also nil in the obj_list.
puts obj_list[0] # nil
What I'd like to do is to change the matrix[y][x] pointer's location (or the reference) so that the matrix[y][x] points to the nil object. In that way, obj_list points to all the correct objects and the matrix cells can address different locations without overriding a HomeMadeObject object by nil (creating nil elements in obj_list).
Edit
I would like to update the objects in obj_list and see the updates in the matrix (so I need to have some kind of a reference here to the original object). But When a HomeMadeObject isn't needed anymore in the matrix, I want to remove it only from the matrix.
All you have to understand here is, In Ruby all variables and constants store references to objects. That’s why one can’t copy the content by assigning one variable to another variable. Variables of type Object in Java or pointers to objects in C++ are good to think of. However, you can’t change the value of each pointer itself.
So use dup method when you are pushing into the object list, your problem is solved.
obj_list.push(obj.dup)
so I have Immutable.js in the form of:
let o = immutable.Map({a: {b: 1}})
and so my question is, would it be valid to do:
o.get('a').b = 2
which will return just the value set, but not a new reference... :/
or other patterns recommended to modidy the internal state of an object literal inside the Immutable map?
I would appreciate if someone can expand on the pattern (if one even exists) of mixing immuatble.js with object literals and recommendations...
tx as always,
Sean.
You are correct in your assumption that the inner object literal is mutable. You can test this as:
var o = immutable.Map({a: {b: 1}})
o.get('a').b = 2;
// b will now be mutated in o;
If you would like to create a fully immutable object use the fromJS method provided with Immutable, which will do a deep conversion, or set the value of a to also be a Map.
Edited to add: Regarding appropriate patterns, I recommend going fully immutable as it maintains the contract that any inner objects/array are also immutable.
I have the following NSMutableArray:
(A|B|C|D|E|255,
F|G|H|I|J|122,
K|L|M|N|O|555)
I am trying to sort the objects in the array using the last component (255, 122, 555). Right now I have the following code:
[myArray sortUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
As expected, this method sorts the array by the first element (A, F, K).
I also read about NSSortDescriptor, for example:
NSSortDescriptor *sort = [[[NSSortDescriptor alloc] initWithKey:#"dateModified" ascending:YES] autorelease];
If I use it, it is not clear what I put as a parameter in initWithKey.
You can use a sort descriptor, which takes the last object of the "inner" arrays and sort by that.
Since sort descriptors use key-value coding (KVC), you need to be aware that arrays respond to valueForKey: in a special way - they pass a normal key on to each of the objects that they contain.
You also need to know that methods which do not take a parameter and return a value can be accessed through KVC is if they were normal properties.
All this adds up to the following:
Each of the objects contained in your array (i.e., the inner arrays) have a key that you want to sort by: lastObject
But since the objects are instances of NSArray they will normally pass the key on to the objects that they contain - which is not what you want.
You therefore need to use a special escape in the key name for that situation, which is #, making the actual key to use #lastObject
So to make a long story short, you can do what you want in this way:
NSMutableArray *array = ... // Your array
NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey: #"#lastObject"
ascending: YES
selector: #selector(localizedCaseInsensitiveCompare:)];
[array sortUsingDescriptors: #[sd]];
You'll notice the "#" in the key name, within the string.
This escape character also works for other collection classes, for instance if you want to access allKeys from a dictionary through KVC, the key you should use is #allKeys.
I would use sortUsingComparator:
[myArray sortUsingComparator:^NSComparisonResult(id obj1, id obj2){
return [obj1.lastPropertyForComparison compare:obj2.lastPropertyForComparison];
}
This method allows you to manually compare the properties or members of the objects that you want to order by. I use it almost exclusively for complex sorts, and I haven't noticed any performance differences.
UPDATE:
If your NSMutableArray contains NSArrays with the last object being the number you're trying to rank by, your comparator would be as follows:
[(NSNumber *)[obj1 lastObject] compare:(NSNumber *)[obj2 lastObject]]
Basically, you are grabbing the last object out of each NSArray, which you know is an NSNumber. You use the compare function to return NSOrderedAscending, NSOrderedDescending, or NSOrderedSame. I hope that helps.
I am using hashtable that contains around 60 key,value pairs.
for assigning the value based on key to any control in my page i have to explicitly type the keyname.
For example:
txtName.Text = htData["Name"].ToString();
txtAddress.Text = htData["Address"].ToString();
Doing this same thing for 60 values is time taking and inefficient.
is there a way to directly get the key and then set the value.
Just like intellisense in vs.
For example:
txtName.Text = htData.Name.Value.ToString();
txtAddress.Text = htData.Address.Value.ToString();
If you are stuck with the Hashtable there is not much you can do. I would suggest switching to the Dictionary class.
You could then make the Key an Enumeration:
public enum DataType
{
Name,
Adress,
...
}
Or you could make an Object with 60 Properties, without using a Dictionary.
If you are stuck with the Hashtable, you could still use an Enumeration, with ToString().
A Hashtable will never provide "nice" code though.
I have data represented in CF as an array of structs e.g.:
var foo = [{key = 'bar', value = 'baz', ... }...];
This structure gets iterated over sequentially and then translated to another related struct which looks like:
foo2[key] = {key = 'bar', value = 'baz', ...};
This is then sent to the SerializeJSON() method and sent to the browser. The problem is that the order of the keys in either foo or foo2 are alphabetical instead of in the order they were added. This is causing a problem on the client side as this collection is iterated over again and is expected to be ordered. Any suggestions?
If your collection is expected to be ordered you need to use an array.
Structs don't guarantee any ordering, and shouldn't be used as such.