I need to remove a node from a linked list using recursion. this is the code that I have so far...
public class SortedSetNode implements Set {
protected String value;
protected SortedSetNode next;
public boolean remove(String element) {
if (value.equals(element))
{
next = next.getNext();
return true;
}
else
{
return next.remove(element);
}
}
Well, without knowing what the problem is that you are facing, you would need a clause in there to check whether the item you are removing is actually in the linked list, i.e.
if(next == null){
return false;
}
Other than that your code looks fine. What is the issue you are encountering?
If the value attribute is the value of the current node, then you'll need to delete itself when value equals element, rather than delete the next. Unless it's the value of next node.
You might need a start point, so when you compare value, you compare the next node's value with the string, and if found, do your next = next.getNext();. Of course a check of null is needed.
Related
I read a lot about this topic and I understand it quit good.
But, the only thing I don't understand is how in functions developers use it without a function that insert the values.
example:
mapping (uint256=>address) public IdToAddress;
after they defines it I see that they are using in functions like:
function HolderOfNFT(Uint256 Id) public returns (address) {
return IdToAddress[Id];
}
How the mapping has value in the Id key that points to the right address?
Thanks a lot!!
All mapping values are empty by default.
So unless the value is set somewhere in the code, your example would return address(0) for any Id.
You can assign a mapping value the same way as you'd assign it to an array. Examples:
IdToAddress[Id] = address(0x123);
function transfer(address _recipient, uint256 _id) public {
require(IdToAddress[_id] == msg.sender, "You're not the current token owner");
IdToAddress[_id] = _recipient;
}
I'm using a Grid in Vaadin 14. The grid is in multi-selection mode.
The selection handler takes a couple of seconds to complete and I'm calling setItems(...) at the end to update the items in the grid.
When the user selects another row while the previous selection handler is still running, I get an "Unknown key" error similar to the one described in https://github.com/vaadin/vaadin-grid-flow/issues/322, even though the new set of items still contains the selected item (another object instance but same according to equals()). This seems to be because the keys in the KeyMapper have already been changed due to setItems(), so the key coming from the client is not present anymore.
Is there a way to work around this, for example by disabling selection while the previous request is in progress?
UPDATE
To work around this Vaadin bug, I'm also calling setPageSize() with the exact number of items as argument. But it seems the same problem occurs even if I don't call setPageSize(), so it's probably due to setItems().
Do not change the grids items inside a SelectionListener.
You can still do all the things you wanted, but setting the items anew is not actually needed. In fact it will only create problems as you are experiencing now.
While working at this answer, I realized you will need to do your own Checkbox Column in order to be able to do actions for the one item that was just "selected", instead of removing all then add all selected ones (because much better performance). Here is how that could look.
// in my code samples, a `Foo` item can have many `Bar` items. The grid is of type Bar.
Grid.Column customSelectionColumn = grid.addComponentColumn(item -> {
Checkbox isSelected = new Checkbox();
isSelected.setValue(someParentFoo.getBars().contains(item));
isSelected.addValueChangeListener(event -> {
boolean newSelectedValue = event.getValue();
if(newSelectedValue){
someParentFoo.getBars().add(item)
} else {
someParentFoo.getBars().remove(item);
}
fooRepository.save(someParentFoo);
});
});
// make a Checkbox that selects all in the header
Checkbox toggleSelectAll = new Checkbox();
toggleSelectAll.addValueChangeListener(event -> {
if(event.getValue()){
someParentFoo.getBars().addAll(allGridItems);
} else {
someParentFoo.getBars().removeAll(allGridItems);
}
fooRepository.save(someParentFoo);
grid.getDataProvider().refreshAll(); // updates custom checkbox value of each item
});
gridHeaderRow.getCell(customSelectionColumn).setComponent(toggleSelectAll);
I solved this problem. Vaadin use data as key in HashMap. You need calc hashCode use immutable data fields. For example
public class TestData {
private int id;
private String name;
public TestData(int id) {
this.id = id;
}
#Override
public int hashCode() {
return Objects.hash(id);
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I have a Job model that contains a number of properties, and a set of linked entities called Quotes:
public class Job
{
....
public virtual ICollection<Quote> Quotes { get; set; }
}
In my Job class I have the following calculated property:
public decimal QuotesAwarded
{
get
{
if (Quotes == null || !Quotes.Any())
{
return 0;
}
var totalUnapprovedQuotes = Quotes.Where(x => x.Status != "Approved");
return 1 - (totalUnapprovedQuotes.Count() / Quotes.Count());
}
set
{
}
}
I have 2 questions:
When I debug this property, Quotes is null (even though there are attached quotes to this entity). I thought that using virtual means that this shouldn't occur? How can I ensure that whenever the model is constructed, the related Quote entities are attached?
The reason I'm doing this is that the property value is stored in the database, so it reduces compute time as it's pre-calculated, is this correct?
Follow up:
In most cases I'm not using Include<Quotes> when retrieving the job object. I'm using Include only when I need the QuotesAwarded value.
However if I don't use Include (say db.jobs.find(id)), and Quotes is null, and the QuotesAwarded value will be 0. So this will get saved to the database when I save the job object, I've really confused myself here.
For your first question, the virtual keyword is used as an indication to Entity Framework to lazily load this. However, it appears that you have disabled lazy loading so you always need to .Include(...) it. As your property is reliant on the quotes being loaded, it will always return 0.
What you are doing is almost right, you just need to let Entity Framework know that your property is a computed column. To do this, you just need to annotate it with an attribute:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public string QuotesAwarded
{
get
{
if (Quotes == null || !Quotes.Any())
{
return 0;
}
var totalUnapprovedQuotes = Quotes.Where(x => x.Status != "Approved");
return 1 - (totalUnapprovedQuotes.Count() / Quotes.Count());
}
private set
{
//Make this private so there's no temptation to set it
}
}
I am facing problem in value change listener.
I have added value change listener in vaadin option group which has six checkboxes.
optionGroup.addValueChangeListener(this :: optionGroupValueChanged);
//..
private void optionGroupValueChanged(ValueChangeEvent valueChangeEvent) {
//...
}
Now I have one another checkbox which selects all the checkboxes of the option group (because it's multiselect). I want to avoid call of value change listener for individual checkboxes so that I first removed the value change listener and added after selecting all as stated below.
selectAllCheckBox.addValueChangeListener(this :: selectAllChecked);
//...
private void selectAllChecked(ValueChangeEvent valueChangeEvent) {
final boolean isChecked = (boolean) valueChangeEvent.getProperty().getValue();
//Following line does not remove the value change listener
optionGroup.removeValueChangeListener(this :: optionGroupValueChanged);
if(isChecked) {
//So here it will call value change of option group six time
optionGroup.getItemIds().stream().forEach( itemId -> optionGroup.select(itemId));
} else {
optionGroup.setValue(null);
}
optionGroup.addValueChangeListener(this :: optionGroupValueChanged);
}
I have checked code of vaadin removeValueChangeListener method it contains markAsDirty(); method. What is the reason of this behavior ? Is there any other alternative solution for my problem ?
Note : Version of vaadin is 7.5.0
That's because this :: optionGroupValueChanged creates each time new instance of ValueChangeListener. You don't want this, you want to remove very specific instance of ValueChangeListener. The solution is to remember (in private field in example) the reference to the listener and pass it in your add and remove ValueChangeListener calls.
optionGroupListener = this :: optionGroupValueChanged;
optionGroup.addValueChangeListener(optionGroupListener);
private void selectAllChecked(ValueChangeEvent valueChangeEvent) {
final boolean isChecked = (boolean) valueChangeEvent.getProperty().getValue();
//change here
optionGroup.removeValueChangeListener(optionGroupListener );
if(isChecked) {
optionGroup.getItemIds().stream().forEach( itemId -> optionGroup.select(itemId));
} else {
optionGroup.setValue(null);
}
//and here
optionGroup.addValueChangeListener(optionGroupListener );
}
this question is basically the same question I asked a few weeks ago... how to tap into mappingcontext.processAnonType... I marked the question as answered by mistake and since then have not been able to get any follow up.
Basically what I am trying to figure out is a location within the breeze pipeline that i can set a non entity object's prototype when the object is materialized from server results... when breeze processes results from the servers that are not entities, it ends up calling the method below of the helper MappingContext class... this method is as follows:
function processAnonType(mc, node) {
// node is guaranteed to be an object by this point, i.e. not a scalar
var keyFn = mc.metadataStore.namingConvention.serverPropertyNameToClient;
var result = {};
__objectForEach(node, function (key, value) {
var newKey = keyFn(key);
var nodeContext = { nodeType: "anonProp", propertyName: newKey };
visitNode(value, mc, nodeContext, result, newKey);
});
return result;
}
up above the value of "results" is what the client ends up receiving from breeze... this is a perfect place that I could do what it is i want to do just because i have access to the final object ("results") AND the node.$type property... i basically want to parse the node.$type property in order to figure out the prototype of the non entity object... unfortunately it does not appear processAnonType is an interception point within the pipeline... in the previous question i asked, i was directed to look at a custom jsonresultsadapter... i did that but i don't think it will work simply because the jsonresultsadapter does not ever appear to be in the position of changing the value of "results" (the final object returned)... so even if i implement a custom jsonresulsadapter and return new nodes, the value of "results" up above continues to be the same... can anyone please clue me in? thank you
EDIT #1: I already tried using a custom jsonresultsadapter… but this does NOT work for what I am SPECIFICALLY trying to do, UNLESS I am using a very old version of breeze (unlikely) or am missing something really obvious (more likely)... down below I have provided two snippets of breeze code that will hopefully help me explain my conclusion... the first snippet is the “visitandmerge” method of the mappingcontext… towards the bottom of that method you’ll see a call made to “jra.visitnode”… that’s great… it calls my custom jra implementation which returns a “node” property in the result such that the following line will use that node rather than the original one… so far so good… then at the end you’ll see that a call is made to “processmeta” that passes in my custom node… ok fine… but then if you look the “processmeta” code in my case the last “else” block ends up being invoked and a call is made to “processanontype”… this is where the problem is… at this point my custom node is discarded for purposes of creating/instantiating the final object returned to the client… I understand my custom node will be used to create properties for the final object but that's not what I am after... instead I need to manipulate the final object myself by setting its prototype… as I mentioned previously, if you look at the “processanontype” method it creates a new object (var result = {};) and that object is returned to the client, NOT my custom node, which is inline with what the documentation says… please see all the comments I left in the previous post... do you understand what my problem is? I am probably missing something here really obvious… can you please clue me in? thanks again
proto.visitAndMerge = function (nodes, nodeContext) {
var query = this.query;
var jra = this.jsonResultsAdapter;
nodeContext = nodeContext || {};
var that = this;
return __map(nodes, function (node) {
if (query == null && node.entityAspect) {
// don't bother merging a result from a save that was not returned from the server.
if (node.entityAspect.entityState.isDeleted()) {
that.entityManager.detachEntity(node);
} else {
node.entityAspect.acceptChanges();
}
return node;
}
var meta = jra.visitNode(node, that, nodeContext) || {};
node = meta.node || node;
if (query && nodeContext.nodeType === "root" && !meta.entityType) {
meta.entityType = query._getToEntityType && query._getToEntityType(that.metadataStore);
}
return processMeta(that, node, meta);
});
};
function processMeta(mc, node, meta, assignFn) {
// == is deliberate here instead of ===
if (meta.ignore || node == null) {
return null;
} else if (meta.nodeRefId) {
var refValue = resolveEntityRef(mc, meta.nodeRefId);
if (typeof refValue === "function" && assignFn != null) {
mc.deferredFns.push(function () {
assignFn(refValue);
});
return undefined; // deferred and will be set later;
}
return refValue;
} else if (meta.entityType) {
var entityType = meta.entityType;
if (mc.mergeOptions.noTracking) {
node = processNoMerge(mc, entityType, node);
if (entityType.noTrackingFn) {
node = entityType.noTrackingFn(node, entityType);
}
if (meta.nodeId) {
mc.refMap[meta.nodeId] = node;
}
return node;
} else {
if (entityType.isComplexType) {
// because we still need to do serverName to client name processing
return processNoMerge(mc, entityType, node);
} else {
return mergeEntity(mc, node, meta);
}
}
} else {
if (typeof node === 'object' && !__isDate(node)) {
node = processAnonType(mc, node);
}
// updating the refMap for entities is handled by updateEntityRef for entities.
if (meta.nodeId) {
mc.refMap[meta.nodeId] = node;
}
return node;
}
}
You should NOT need to modify the processAnonType method.
The parameters to the visitNode method in the jsonResultsAdapter have all of the information regarding the node being visited that you say you need. (See the link at the bottom of this post). The result from the visitNode is an object with the following properties:
entityType: you should return null for an anonymous type
nodeId and nodeRefId: ( probably not needed for an anonymous objects unless you plan to return multiple refs to the same object)
ignore: boolean - (if you want to completely ignore the node).
node: This is where you can take the incoming node ( the first parameter in the visitNode parameter list) and modify it, or return a completely new node object that represents your anonType instance. This object will be returned to the client unchanged, so you can create an new instance of your object with whatever prototype you want. If you don't set this property then the original incoming node will be used.
passThru: (avail in breeze versions > v 1.5.4) boolean - you should return true to return the node (above) intact without ANY further processing.
So your visitNode will look something like this:
visitNode: function(node, mappingContext, nodeContext) {
// 'isAnonType' is your method that determines if this is an anon type
var isAnon = isAnonType(node.$type);
if (isAnonType) {
// 'createCustomAnonNode' is your method where you create a copy of the node with whatever prototype you want.
// prototype you want.
var newNode = createCustomAnonNode(node);
return {
return { passThru: true, node: newNode };
}
} else {
// assuming that you kept track of the default JsonResultsAdapter;
return defaultAdapter.visitNode(node, mappingContext, nodeContext);
}
}
For more detail, see:
http://www.getbreezenow.com/documentation/jsonresultsadapters