dart removeWhere() - where does the data go? - dart

I am trying to write a function in dart that takes a string that has some words that be begin with a "#" character and split it into two sets. One that contains string with only the "#" character and one with no "#" characters.
There are some obvious ways i could do this with a for loop, but want to use these fancy list processing functions (what are these called exactly?) like where() forEach().
so here is my attempt.
void main() {
String inputText = "Hello world. #hithere";
inputText.split(" ").where((element) => element.startsWith("#"))
.forEach((item) {
print(item);
});
inputText.split(" ").removeWhere((element) => element.startsWith("#"));
print(inputText);
}
Here is the output of the program:
#hithere
Hello world. #hithere
the first part works as expected, but the second part i expected the removeWhere would remove the element #hithere from my list....
but this this didnt happen.
So my question is this. Did the removeWhere() method remove this element correctly? If so where is the list that has this element removed? How do i get access to it?
my explanation of what happend is that the split(" ") method created a List and the removeWhere() method operated on this List and removed the element i told it to... but what i dont understand is how i can get access to this list? where does this list exist?
what i was think i should do is something like this:
inputText.split(" ").removeWhere((element) => element.startsWith("#")).join();
I was hoping that i could take the List with the removed elements and join() them back into a string... but since the removeWhere() method returns void.. i have no idea where the list that has removed elements exists?

Related

Array of object append not working on swift [duplicate]

I am currently having trouble filling up an array of customClass.
I try to fill it with a jsonFile. During my json parsing (using swiftyJSON) i loop and fill my array.
The problem is, at the end of my loop, it is still empty. I tested it in different ways, and here is my code:
That's the file where the problem is. In my loop I fill an Annotation, that I add with append to my array. The problem is what my print return. Here is a part of it:
It's just a small part of a huge jsonfile. And, my tmpAnnot.name is correctly printed every iteration. But when it comes to my Array, nothing.
So I'm completly lost and hope you could help me ^^
(And for the information, here is my custom class) :
And btw, I tried to print my array.count, and it's nil too
Im so sorry if the question has been posted. I couldn't find it in the entire website.
Change your JSONAnnotationList declaration to be an non-optional and assign it an empty array
var JSONAnnotationList: [UGOAnnotation] = []
You see, you have never created an array so there was nothing to be printed.
The whole point of optionals is to use them sparingly, not everywhere.

Redefining TCL foreach

I would like to redefine TCL's foreach, since multiple applications of foreach break some code.
Detailed problem description
The actual case where the code breaks happens in Vivado, a program using TCL for scripting. They supply an API that specifies get_<someObject> methods, which returns a list of objects (actually something that behaves like a list, but is implemented by xilinx to handle caching/printing a bit differently). To handle these lists I use foreach. The first time I use foreach on the list, I get <objects> in the loop variable.
However, if I apply foreach on a single object, the object is converted into a string representing its name. The problem is, that the API function get_property expects an object.
While applying foreach twice, does not seem to make sense, this might happen if you write two functions that take a list of objects and operate on them.
i.e.
proc a {obj} {
puts "logging [llength $obj] objects:"
foreach o $obj {
puts "$o has column index [get_property COLUMN_INDEX $o]"
}
}
proc b {obj} {
foreach o $obj {
a $o
puts "working on $o"
get_property COLUMN_INDEX $o
}
}
If we now call these functions as follows
a [get_clock_regions X0Y0] # ok (the list is turned into single objects in foreach)
b [get_clock_regions X0Y0] # crashes inside a (the list from get_clock_regions is
# turned into objects by the foreach in b
# a is then called with a single object,
# the foreach now turns the object into a string
# representing the name, but get_property
# does not work on strings => error
I asked if the behaviour can be fixed in this question on the Xilinx Forums, however I am looking for a workaround for the meantime.
What I am trying to do
I would like to implement a workaround for the meantime. While I can do
a [list $o]
inside b, I think it would be nicer if I can redefine foreach to not break the above case. This way, I can simply drop my redefinition of foreach if Xilinx can fix the behaviour. (I am expecting foreach to work the same regardless if I have a list with one element or a single element, to my understanding this is the same in TCL).
My issues with redefining foreach are:
How do I know if foreach is called as
foreach {varA varB} {valueList} {...}
foreach {varA varB} {valueList1 valueList2} {...}
Is there a way to test if I have an object or a list containing one object? The Idea is two detect if it is just an object, if so wrap it into a list, which then can be unwrapped back to object by the normal foreach, however I have no clue how to detect this case.
Outline code I would like to write:
proc safeForeach {varnames valueLists body} {
if { thereAreMultiple valueLists } { # this issue no 1
foreach valueList $valueLists {
if {wouldDecayToString $valueLists} { # this is issue no 2
set valueLists [list $valueLists]
}
}
} else {
if {wouldDecayToString $valueLists} { # this is issue no 2 again
set valueLists [list $valueLists]
}
}
#the next line should be wraped in `uplevel`
foreach $varnames $valueLists $body
}
The root cause of the problem is (using your example) invoking proc a, which expects a list, with only a single scalar value when it is called in proc b. Your "workaround" of invoking a as, a [list $o], is the solution. It converts a single value into a list of one element. A list containing one element is not the same as a single value. Since lists in Tcl are just specially formatted strings, if the argument to proc a contains whitespace it will be treated as a list, split up into the whitespace separated components. Although Tcl is flexible enough to allow you to radically redefine the language, I think this is a case of "just because you can, doesn't mean you should." I just don't think this case is compelling enough since some code refactoring would make the problem disappear.
Ultimately, the issue is that you don't want to treat simple values as lists. One of the ways of dealing with that is indeed to use [list $a] to make a list out of the value that shouldn't be mistreated, but another is to change the a procedure to take multiple arguments so that you can treat them as a list internally while having quoting automatically applied:
# The args argument variable is special
proc a {args} {
puts "logging [llength $args] objects:"
foreach o $args {
puts "$o has column index [get_property COLUMN_INDEX $o]"
}
}
Then you can call it like this:
a $o
When passing in a list to a procedure like this, you want to use expansion syntax:
a {*}[get_clock_regions X0Y0]
That leading {*} is a pseudo-operator in Tcl, which means to interpret the rest of the argument as a list and to pass the words in the list as their own arguments.

Find pages with tag

In a Umbraco 7 solution, i have a Tags Content picker on all pages. Pages can with this, set tags on each page.
I then want to get alle pages, within the intire site, that has, lets say tag 111 (id, not name).
I have tried with:
var ids = Model.MacroParameters["tags"]; //the tags to show
CurrentPage.AncestorOrSelf(1).Descendants().Where(x => ids.Contains(x.tags.ToString()));
But that gives me the error:
Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type
Whats the correct way?
Solved it with;
Umbraco.Content(rootId).Descendants().Where("tags.Contains(#0)", ids);
You have a few options, depending on whether you prefer a dynamic or strongly typed view model.
Strongly Typed API
Umbraco.TypedContentAtRoot().Descendants().Where(x => x.tags.Contains(ids));
Dynamic API
Umbraco.ContentAtRoot().Descendants().Where("tags.Contains(#0)", ids);
Please note that the Contains statement may give you inconsistent results, as the tags property seems to be returning a comma separated list. In that case you can try splitting the string or install the Core Property Value Converters package and get the tags as IEnumerable<IPublishedContent>
Always try to avoid using Descendants, especially on the root node.
To get the tags for a property:
ApplicationContext.Current.Services.TagService.GetTagsForProperty(Model.Content.Id, "propertyname")
To find content with a specific tag:
ApplicationContext.Current.Services.TagService.GetTaggedContentByTag("tag")

Best way to handle where clause in Lambda

I have the following lambda for a simple search page using MVC:
Name and PostedName are strings.
Results.where(a=>a.Name.Contains(PostedName)).ToList();
Thanks great when PostedName has a value (excellent filter), but when it is empty, I get bupkas (empty list).
I would ideally like my where clause to be ignored when empty string.
How can this be done?
Something ideally shorthand without ifs and elses and whatifs.
Thanks!
You can dynamically add the WHERE clause. Keep in mind that you're just building an expression tree with these clauses and it's not actually executed until, in this case, you call .ToList(). So you can do something like this:
var filteredResults = Results;
if (!string.IsNullOrWhitespace(PostedName))
filteredResults = filteredResults.Where(a => a.Contains(PostedName));
filteredResults = filteredResults.ToList();
Depending on the types you may need to explicitly declare a type for filteredResults in order for that to compile.
If you want something a little more in-line, this may do the trick:
Results.Where(a => string.IsNullOrWhitespace(PostedName) || a.Contains(PostedName)).ToList();
I think it's less clear on the intent, though. The benefit of the first example is also that you can add more filters following the same structure, basically dynamically adding more WHERE clauses for other filter fields as needed.
David's answer is correct, but if you want a shortcut you can create an extension method to simplify usage example (untested by me).
I would suggest:
Results.Where(a => a.Name.Contains((PostedName ?? "").Trim())).ToList();
"ThisIsAString".Contains("") returns true.
In the case PostedName is null, it will be changed to "".
If there is leading and/or trailing blanks characters in PostedName, then they will be removed.

The 'tap' method on String object doesn't return expected result

I ran in to an interesting problem while using the 'tap' method on objects of type 'String'.
"abc".tap { |o| o = "xyz" } # this line returns "abc" instead of "xyz"
The 'tap' method works on objects of other types.
[].tap { |o| o << "xyz" } # this line returns ["xyz"] as expected
I am using Rails 2.3.2 and Ruby 1.8.6 on Windows XP.
What am I missing here?
Update 1: I resolved this issue. It was an usage error on my part. In the first scenario I was re-assigning the value to the block parameter instead of modifying it. I was able to rewrite the code and get the expected result.
"abc".tap { |o| o.replace "xyz" }
Update 2: Code used here is just to demonstrate the problem. My actual code does not look like this.
Object#tap always returns the original object passed into it after executing the block, even if the block returns something different.
The benefit here is that you can put tap into the middle of a chain and test the value of an object without modifying the original value.
This means that if you pass "abc" into tap, it'll execute the block and return "abc". Your assignment to o doesn't mean anything due to scoping. Likewise, if you pass an empty array into tap, it would return an empty array back. However, in your second example, you modified the original value. Operations that modify the original such as << or gsub! or likewise will modify the object before its returned, therefore you get a different value back.
Check out http://moonbase.rydia.net/mental/blog/programming/eavesdropping-on-expressions for some more cool examples about how to use tap. Don't use it for assignment or modification or you'll get back wonky results.
Update: To your edit, why does that resolve your issue? I don't understand why you'd call tap to do a replace when you can just call replace on the object itself. What benefit is tap providing you?

Resources