Remove similar items on an object list - c++

I am populating a std::list<item*> itemslist from a text file, but there are instances where the name variable is the same, in those instances I want to remove the duplicated item (the item with the same name, other information of the item is irrelevant) but get data from that object to add to the 'original' (the first instance of the item)
Because I want to be able to load multiple information, aka an array of sorts into 'items' and this is what I have so far come up with
I tried to loop through items, then loop again and check the first loop against the second loop, copy the information and add to the array of the first loop item but it just breaks.
Suggestions?
Similar to this: Removing duplicates in a vector of strings
Except I want to use the information found in any duplicate and add it to a std::list that the item object holds
So if I load this:
Set Normal DIfficulty|Sets your save game to normal difficulty|/JKSV/Saves/Fire_Emblem__Awakening/hack/Chapter0|0x0D|0x00
Set Normal DIfficulty|Sets your save game to normal difficulty|/JKSV/Saves/Fire_Emblem__Awakening/hack/Chapter0|0x0F|0x0A
Set Hard DIfficulty|Sets your save game to hard difficulty|/JKSV/Saves/Fire_Emblem__Awakening/hack/Chapter0|0x0D|0x01
Set Lunatic DIfficulty|Sets your save game to lunatic difficulty|/JKSV/Saves/Fire_Emblem__Awakening/hack/Chapter0|0x0D|0x02
Set Lunatic+ DIfficulty|Sets your save game to lunatic+ difficulty|/JKSV/Saves/Fire_Emblem__Awakening/hack/Chapter0|0x0D|0x03
It will only have 1 Set Normal Difficulty item but that item will hold the duplicates last 2 pieces of information (aka 0x0F|0x0A

If you want your std::list<T> to erase duplicate values you have to call unique member function. There are two overloads of it. First take 0 arguments and compares values using operator==. It is not your case cause your list contains pointers and you don't need to compare addresses but name members. So try a second one. It takes a binary predicate where you can compare members
std::list<item*> myList;
// populate your list..
// sort it before calling unique..
myList.sort([](const item *lhs,const item *rhs)->bool{
return lhs->name < rhs->name;
});
myList.unique([](const item *lhs,const item *rhs)->bool{
return lhs->name == rhs->name;
});
// now your list has no duplicates..
More info here.

Related

gdb: how to make a filtering query for displaying a structure in a container?

In gdb currently I can print the contents of a container, such as std::list, which contains a structure type. This type, however, is quite large and I need only values of some selected fields in every item from the container. So, let's say, I have a structure that contains about 100 fields and I have 3 items in the container and need to display the type field. So:
(gdb) p items
will display lots of noise, while
(gdb) p items[0].type
won't work with std::list, moreover, with list I can easily display the value of only the first item (other require lots of spaghetti with typecasts, fields reaching etc.), while I need someting, say:
(gdb-maybe) p {foreach i: items} i.type
which would display every item just like the container printer does normally, except that the displayed values will only contain the type field.
Is there any way to achieve anything like this, or maybe some method to provide such a solution using a script?

How to delete duplicate constructed objects in a list while preserving order and returning a List in dart?

I have a list of constructed objects called RecentCard which is basically an object with user id, pic, and name. I have created a list arranged in order of most recent interaction based on timestamp. However i need to get rid of the second occurence and onwards of any duplicated object. I am comparing just the ids since users may have the same name or photo, and i cannot remove duplicates from a simple list of uids because then i could lose the order of corresponding photos and names.
For example the list would look something like this :
List<RecentCard> recentCards= [RecentCard(uid:as721dn18j2,name:mike,photourl:https://sadadasd1d1),RecentCard(.....]
I have searched for solutions but all of them are dealing with like primitive types like simple lists of strings and the solutions didn't work for me. For example this post: How to delete duplicates in a dart List? list.distinct()? Read below
The first answer's link is no longer available, the next answer with sets is something i tried but it simply doesnt work i have no idea why maybe because its not a primitive type. The next answer with the queries package didn't work because i was using the list to build a listview.builder and so when i called list.length it said i couldnt call that on an iterable or something. The final solution wouldn't work because it said String is not a subtype of RecentCard.
I tried using two forloops with the second just comparing first value to the next couple but that doesnt work because if a duplicate is found, the object is removed and the length is messed up so some elements get skipped.
Any ideas? I feel like its very simple but im not sure how to do it.
You have to use Set to store seen cards and then filter away those ones that are already in the set.
final seenCards = Set<String>();
final uniqueCards = recentCards.where((card) => seenCards.add(card.uid)).toList();

Polymer - dom-repeat & caching of element data in DOM tree

following scenario:
I have a Firebase database containing a list that is used to create a set of "paper-cards" with dom-repeat:
<template is="dom-repeat" items="{{items}}">
<my-element card="{{item}}">
<paper-card id="{{card.id}}">
...
</paper-card>
</my-element>
</template>
In the UI, the user can add or delete paper-cards, so items also get deleted in Firebase.
Now I realized if I change the CSS of an element (e.g. fadeIn, fadeOut animation) and afterwards delete a card and later add one card, the card still has the CSS state as it was before (e.g. for fadeIn/fadeOut animations).
My questions:
How does DOM repeat deal with elements added or removed? Is not all information of this element "deleted"?
If I delete item #5 (out of 10), what happens to elements 6-10, are they deleted and re-created as "5-9" or "moved/altered"?
Besides CSS, are there any other implications that should be considered inside the template tag? Do I need to manually reset anything?
You can read about the dom-repeat on https://www.polymer-project.org/1.0/docs/api/dom-repeat but what it basically tells you that it tries to be too smart without asking the developer if it wants that behavior. The dom-repeat is heavily flawed because of this.
Polymer is saving performance to doing a dirty check, basically looping through everything and only changing the DOM if the checked values (id, in this case) changes. This means that it will inherit other values.
Basically, it wont update sub-properties. This means that dom-repeat isn't really made for any kind of update.
You can possibly go around this issue by using Polymer's this.splice(). It works like the splice in javascript but sends out an event to dom-repeat to update and where to update. Remember however, that arrays in Javascript are references, so if you take this.items and try to modify it, it will automatically update values the dom-repeat (without updating DOM) and then it will dirty check the update with the new values and not change anything at all. If you want to modify the array in the dom-repeat, then use JSON.parse(JSON.stringify(array) first to get rid of the reference.
Another thing you can do is to use the unique id. If the id changes for that specific card, then hard reset all values and initialize that specific card once again with all it's normal properties (including CSS). That's the workaround I use all the time.
The desperate thing to do, when nothing else works, is to nullify the array that keeps track of the cardset, with this.set('items', []) and then set the property with the new array.
The repeater evaluates the number of items in your array on initialization and stamps that many template instances into the DOM. If you delete an item from your array the repeater is presented with a new array that is one element less, removes the last one and propagates data change to elements' instances.
So if you start with 10 elements and order to delete #5 then element's #6 data is inserted via data-binding into the same DOM node that previously contained #5 data, and so on down the list. The last DOM node for which the updated array contains no data will be removed from the DOM tree.

How to give a model object an order (or index), which can be reassigned?

Say you have an ordered list. You order the list based on a model field called "index". So the first item has an index of 0, the second has an index of 1 and so on...
The index is unique to that model object.
How would you implement this?
I want to be able to create more instances of the model object, where the index is assigned to the next available index (add the object to the end of the list). And then be able to reorder the list so that if you change the index of an object, all the following object's indexes increase by one.
If you want an IntegerField that increments itself you can use the id. It's unique for that model and Django generates it automatic. And you can order by this using
inverse:
MyModel.objects.all().order_by('-id')
Normal order:
MyModel.objects.all().order_by('id')
If you just have a field that contains auto-increment-index don't need to create another one only if you can modify it, but if this index is unique you cannot edit it to prevent duplicates. Si I would use the id MyModel.id
Here you have the documentation for .order_by()
There is no field that does that automatically. Have you looked in to using signals for this? You could hook up a signal that detects an index change, and triggers a function that updates the index of every object whose current index is greater than the one being removed/changed.
You may ave to rethink your schema because if you change the index of your first element in the list which has lets say 1 million elements, you are gonna update 1 million objects! You may save for each object its left and right "neighbour" and create a method to get the list.

Can I remove items from a ComboBox without changing the index of other items?

I have a CComboBox control with several items and I need to remove some of them, but the indexes of the remaining items should be preserved.
When the combo box is populated, the item data is set like so:
index = mycombo.AddString(temp);
mycombo.SetItemData(index, static_cast<DWORD>(count));
where count is a loop counter, and should be equal to index
Now I want to remove some of the items later, but I need the index of each remaining item to stay the same. Is CComboBox::DeleteString(UINT nIndex) what I should use? Its documentation says:
All items following nIndex now move down one position. For example, if a combo box contains two items, deleting the first item will cause the remaining item to now be in the first position. nIndex=0 for the item in the first position.
Is that talking about the physical location in the drop-down menu, or the index value associated with the item?
Is there another function that does what I need? Another solution altogether?
Is that talking about the physical location in the drop-down menu, or the index value associated with the item?
For a ComboBox (as well as ListBox, List Control, and probably many other such things) the location of an item on the control is directly tied to its index. The index is the location. Really, just think of it as if ComboBox was implemented internally using a simple std::vector. You can't remove an entry from a vector without affecting the indexes of all subsequent entries, and it is just the same with these controls.
However, the Item Data of an entry in a ComboBox (and other such controls) sticks with that entry no matter what index it is reassigned to.
Say you created two entries: the first at index 0 has text="A" and ItemData=0; while the second at index 1 has text="B" and ItemData=1. If you then remove that first entry, the second entry will shift down the claim the index and its ItemData will travel along. So you would be left with a single entry at index 0 having text="B" and ItemData=1.
In a combobox you have items which have a string and an integer value associated. Normally, you just see the string. Those items are referenced by an index, which just represents the location of each item in the list. If you remove an item, all the items below it are "relocated", so the index changes. The same happens in you insert an element anywhere between two items, or at the beginning.
The index always goes from 0 to (number_of_items-1), and there's nothing you can do about it.
That said, the item data always stays with the item, and it's this what you should look at when looking for a specific item. Not its index, and neither its string. Look at the item data. The index can change if you add, remove or resort the items. The strings will change if you localize the software. So use the data to properly identify each element.
You can take a look at http://www.flounder.com/combobox.htm, where you can find a better explanation, with some examples and code to do work with comboboxes more easily.
Adding or removing items does not change the number you passed to SetItemData(). GetItemData() returns the same number. You however need to pass the index of the item to DeleteString(). When lower numbered items were deleted before then the index will no longer match GetItemData(). If you lost track of the index of a specific item you want to delete then you need to iterate the items to find it back.