Is there a collection type in f# that has an "append" method, such that I can add an element to that collection as such:
(pseudo code)
let list = [1,2,3,4]
list.append( 5 )
print list
result : 1,2,3,4,5
Basically i need a collection that can grow at run time, I cant assume what size it will be.
I couldn't find a way to do this with list or array in f#
UPDATE: I dont want to create a new list/array every time this will be happening many times. I want to append the already existing collection. I need to use the same name/symbol for the collection. F# doesn't allow me to redeclare or over write a collection, so this wouldnt work:
let A = [1,2,3]
let A = A.append 4 or A <- Array.appen A 4
You can use ResizeArray:
let list = ResizeArray([1;2;3;4])
list.Add( 5 )
In my opinion what You want achieve has little to do with functional approach. I wouldn't hesitate to use standard .NET List for that.
Regarding Your update:
Since the lists are immutable, it's not that a new list is created every time You're prepending an element to a list. This is much smarter than copying whole existing list.
Related
I am working on UISearchBar on Swift 4.0. I have originalList[ModelItem] and filterList[ModelItem]. While in searching lets say user wants to delete on filterList 5th position which is 10th item on actual originalList. It make sense to delete this item from both of the list right? Items have no id or similar type field.
What would be the basic steps for such both-way deletion? I was looking for a general idea of achieving this.
If the model is a class and the filterList is created directly from the originalList (no new objects created, but both lists reference the same objects), then you can use this code:
let itemToDelete = filterList.remove(at: indexPath.row)
if let index = originalList.index(where: { $0 === itemToDelete }) {
originalList.remove(at: index)
}
print(originalList)
print(filterList)
=== operator will test the equality of the instances, thus identifying the proper instance to be removed from originalList.
In case you are using struct as a model, you will have to implement Equatable with some heuristics that would be able to detect if two instances are equal or not even without having an explicit identifier and then use == to find the proper instance in originalList to be removed.
Another alternative might be implementing search with index method, that would use the same filtering algorithm as your current filter method, but would take one more parameter - index in the filterList (filterIndex) along with the filter text, and based on that would compute and return an index in the originalList that matches the provided pair of filter text and filterIndex.
Yet another alternative, which I would not recommend (I would call it a hack) - you can keep a dictionary of indexes from originalList to filterList which you can use to have explicit mapping between originalList and filterList. This would however require that you always update that dictionary whatever change is made to one of the lists - every search, every deletion or removal or insertion would require an update of the mapping dictionary. This seems way to complicated and error prone.
You have a number of options.
You can maintain a mapping between the original and the filtered items positions, so you can perform deletion on both lists.
You can make your items identifiable, so you can search for the corresponding item in the original list and delete it. Note that all reference types can be tested for identity (===).
You can work with a filtered "view" to the original list, and not with a filtered copy, so the deletion will be performed on the original list naturally.
I don't think we have a standard solution for the latter option, which makes this approach the most complicated.
When choosing either of the first two options be careful with the original list updates that can happen while you operate on the filtered copy.
I've gotten close, I believe. My current query is this
items = Item.select("items.icon, items.name, item_types.name AS type, items.level, items.rarity, items.vendor_value")
.joins(:item_type)
.where("item_types.name = '#{params[:item_type]}'")
This gets me an array of Item objects that at least respond to :type with the item_type.name.
What I am looking for is an array of arrays that look so:
[icon, name, item_type.name, level, rarity, vendor_value]
I've already had it working fairly easily, but it is important to me that this be done in one fell swoop via sql, instead of creating a map afterwards, because there are times where I need to respond with 40k+ items and need this to be as fast as possible.
Not sure how to go from the above to an array of attributes, without performing a map.
Thanks for your help!
The pluck method does precisely what you want. In your case, it would look like this:
items = Item.joins(:item_type)
.where("item_types.name = ?", params[:item_type])
.pluck("items.icon", "items.name", "item_types.name AS type",
"items.level", "items.rarity", "items.vendor_value")
I also changed the where call to use parameterization instead of string interpolation—interpolation isn't recommended, especially when you're getting a value from the user.
Further reading:
Official documentation for pluck
An in-depth explanation of how to use pluck
I am looking for a template of sorts for merging two linked chains that have already been sorted. I'm still fairly new to Java, and this seems to be a pretty challenging task to accomplish with the limited knowledge I have. I have an understanding of how to merge sort an array, but when it comes to linked lists I seem to be drawing blanks. Any help you all could give me, be it actual code or simply advise on where to start, would be greatly appreciated.
Thank you for your time!
If the two linked list are already sorted, then it is so easy to merge those two together. I am gonna tell you the algorithm but you need to write the code yourself since it seems like a school project. First you make a new linked list, and then assign the head of the new list to be the min of list1Head and list2Head, then you just walk the two list, each time picking the min of the current node of the two list and append to the new created list, make the current to be .Next if it got picked. If one of the list doesn't have more nodes, then append the rest of another list directly to the new list. Done
Can't you look at the first element in each list and take the smallest. This is the start of the new list. Remove this from the front ofwhichever list it came from. Now look at the first element again and take the smallest and make it the second element in the new list. Then just repeat this process zipping the two lists together.
If you want to avoid creating a new list the just find the smallest then look at the thing is pointing at and the beginning of the other list and see which is smaller. If you are not already pointing at the smaller one the update the pointer so it is. Then rinse and repeat.
i want to get specific element in a Set in JSF 2
please advise how to do that.
This problem is not specific to JSF/EL. Already in plain Java you cannot access a specific element in a Set. The Set has no method like get(index) as the List has. You need to convert the Set<T> to a T[] array or a List<T> so that you can access it by an index.
This works in a predictable way for SortedSet or LinkedHashSet only as the elements are then inserted in respectively the sorted order or insertion order. This would not make any sense when it's a HashSet as you cannot reliably predict beforehand at which index the element would end up.
If you're using EL 2.2 (your question history confirms this), then you can just use Set#toArray() to convert it to an array and then use the brace notation [] to access the element by index. The below example prints the second item of the array representation of the #{bean.someSet}.
#{bean.someSet.toArray()[1]}
Again, this makes no sense if it's an unordered set like HashSet.
Your problem is quite unclear, but JSF2 doesn't really support Set.
Components like ui:repeat or h:datatable always need a sort to display data, so your best choice will be to convert your Set to a List first.
I am trying to change the index of a node, because there are some specific nodes that at all times needs to be at the bottom of my tree. I tried to change the Node.Index, but that did not change anything. So my question is: How do I change the Index of a PVirtualNode?
Thanks! - Jeff
To change the index of node A, find the node B that has the index you want A to have, and then call Tree.MoveTo(A, B, amInsertBefore, False). B and everything after it will shift down by one to make room for A, and their Index fields will be recalculated. This works even if A doesn't yet exist in the tree (such as just after calling MakeNewNode).
If you're using Index to associate each node with its corresponding data value in a list or array, then you'll find this largely ineffective for re-ordering the displayed values.
You canot change the index of a node. Normally when using VirtualStringTree you hold your data in your own data structure separate from the tree and access the data from the events.
You can also store data directly in the nodes (using a record), but I prefer the other approach because it keeps the logic out of the tree view.
For example, you could store the data in a list and access this list in the GetText handler (you can use Node.Index). Then, if you want to reorder the items, just reorder your list and everything else will happen automatically (you might have to call Invalidate on the tree).
Pseudocode:
Initializing:
Tree.RootNodeCount := MyList.Count;
In the GetTextevent:
NodeText := MyList [Node.Index];
Reordering:
Reorder (MyList);
Tree.Invalidate;
Given that you are still using the tree view control as a container, the ideal solution offered by Smasher is not available to you.
One rather obvious solution, given that your tree view has no hierarchy (i.e. it's a list) would be to use the Sort method with your own compare function (OnCompareNodes).
The other blindingly obvious strategy would be to add the node that you want at the bottom last. If you need to add other nodes later, then insert them above the special last node with InsertNode. This simple approach will probably suffice for the problem as you have described it.
TVirtualNode is a doubly-linked list, it's not a index-based structure: you change the index of a node by removing it and adding it where you want it.
Look into DeleteNode and AddChild.