Dart multiple function calls/set variables all on one line - flutter

I need to clear some Lists at the start of a function otherwise they just get larger and larger with an add method, so I can either use = [] or .clear() to achieve this, but the formatting puts them all on separate lines like this:
listone.clear();
listtwo.clear();
three.clear();
listfour.clear();
listfive.clear();
listsix.clear();
I want to do something like this but it won't allow it:
listone.clear(), listtwo.clear(), three.clear(), listfour.clear(), listfive.clear(), listsix.clear();
or
listone = [], listtwo = [], three = [], listfour = [], listfive = [], listsix = [];
How do I set multiple variables that have already been declared all on the same single line?

The easiest way to make complex things fit in less space is to use a helper method.
clearAll(Iterable<List<Object>> lists) {
for (var list in lists) list.clear();
}
then you just write:
clearAll([listone, listtwo, three, listfour, listfive, listsix]);
You can inline the helper function
for (var l in [listone, listtwo, three, listfour, listfive, listsix]) l.clear();
but it probably won't fit on one line anyway.
If you are setting variables, and you set the variables to the same value, then you can do multiple assignments as a single expression:
listone = listtwo = three = listfour = listfive = listsix = [];
Not really recommended for lists because then all variables will point to the same list object. It works better when assinging null or another immutable value.
It's not particularly readable either.
There is no simple way in Dart to execute multiple expressions in a single statement without some helper.
You could declare:
void do6(void v1, void v2, void v3, void v4, void v5, void v6) {}
...
do6(listone.clear(), listtwo.clear(), three.clear(),
listfour.clear(), listfive.clear(), listsix.clear());
but you will likely find that will be formatted on more than one line as well
Alternatively, just use a list literal instead of a function parameter list to allow multiple expressions:
[listone.clear(), listtwo.clear(), three.clear(),
listfour.clear(), listfive.clear(), listsix.clear()];
Same caveats about length and formatting, and it's confusion and inefficient that the list is created and then not used.
All in all, please don't try to be clever with formatting. Just write idiomatic code, your readers will have a much easier time understanding it, and the compiler will be more efficient that way.

This is what you can do
void main() {
var listone = [1, 2], listtwo = [1, 1, 1], listthree = [0, 0, 1];
[listone, listtwo, listthree].forEach((l) => l.clear());
print(listone);
print(listtwo);
print(listthree);
}
Check at dartpad
Note: There should be no trailing comma like [x,y,z , /*this one*/] or dartfmt will take it to next line.
EDIT:
Also, if using the same thing in multiple files then
put in a global file
clearList(List list)=>list.clear();
and call something like
[listone, listtwo, listthree].forEach(clearList);

Related

Return keyword inside the inline function in Scala

I've heard about to not use Return keyword in Scala, because it might change the flow of the program like;
// this will return only 2 because of return keyword
List(1, 2, 3).map(value => return value * 2)
Here is my case; I've recursive case class, and using DFS to do some calculation on it. So, maximum depth could be 5. Here is the model;
case class Line(
lines: Option[Seq[Line]],
balls: Option[Seq[Ball]],
op: Option[String]
)
I'm using DFS approach to search this recursive model. But at some point, if a special value exist in the data, I want to stop iterating over the data left and return the result directly instead. Here is an example;
Line(
lines = Some(Seq(
Line(None, Some(Seq(Ball(1), Ball(3))), Some("s")),
Line(None, Some(Seq(Ball(5), Ball(2))), Some("d")),
Line(None, Some(Seq(Ball(9))), None)
)),
balls = None,
None
)
In this data, I want to return as like "NOT_OKAY" if I run into the Ball(5), which means I do not need to any operation on Ball(2) and Ball(9) anymore. Otherwise, I will apply a calculation to the each Ball(x) with the given operator.
I'm using this sort of DFS method;
def calculate(line: Line) = {
// string here is the actual result that I want, Boolean just keeps if there is a data that I don't want
def dfs(line: Line): (String, Boolean) = {
line.balls.map{_.map { ball =>
val result = someCalculationOnBall(ball)
// return keyword here because i don't want to iterate values left in the balls
if (result == "NOTREQUIRED") return ("NOT_OKAY", true)
("OKAY", false)
}}.getOrElse(
line.lines.map{_.map{ subLine =>
val groupResult = dfs(subLine)
// here is I'm using return because I want to return the result directly instead of iterating the values left in the lines
if (groupResult._2) return ("NOT_OKAY", true)
("OKAY", false)
}}
)
}
.... rest of the thing
}
In this case, I'm using return keyword in the inline functions, and change the behaviour of the inner map functions completely. I've just read somethings about not using return keyword in Scala, but couldn't make sure this will create a problem or not. Because in my case, I don't want to do any calculation if I run into a value that I don't want to see. Also I couldn't find the functional way to get rid of return keyword.
Is there any side effect like stack exception etc. to use return keyword here? I'm always open to the alternative ways. Thank you so much!

How to loop through two lists at the same time - Flutter

I'm trying to loop through two lists at the same time
For example
List A = ['Chapter 1','Chapter 2','Chapter 3'];
List B = ['Paragraph 1','Paragraph 2','Paragraph 3'];
for(var chapter in A) // This would itreate through only first list (A), How can I iterate through both list
children: [
Text(chapter);
Text(paragraph);
]
I need to iterate through both lists at the same time in "for" loop.
Here is the code:
List A = ['Chapter 1','Chapter 2','Chapter 3'];
List B = ['Paragraph 1','Paragraph 2','Paragraph 3'];
for (int i = 0; i < A.length; i++) {
print ("${A[i]}");
print ("${B[i]}");
}
Let me know if this does not help.
final c = zip([a, b]).map((item) => Foo(item[0], item[1])).toList();
I went along with Randal Schwartz's note about IterableZip. Note that I was not able to find any zip mentioned by Gbenga, and also note that package:collection/iterable_zip.dart is deprecated, you'd need to import simply the collection.dart, like so:
import 'package:collection/collection.dart';
final A = ['Chapter 1','Chapter 2','Chapter 3'];
final B = ['Paragraph 1','Paragraph 2','Paragraph 3'];
for (final pairs in IterableZip([A, B])) {
print(pairs[0]);
print(pairs[1]);
}
Some more notes:
final A and final B variables will be typed List<String> lists, I disadvise dynamic List A.
I have not specified template type for IterableZip, but in some cases (in a complex case where I used it) you may need to explicitly type it like IterableZip<String>, so in the loop you can more conveniently access the members. In this simple case the compiler/interpreter can infer the type easily.
Some other answers in other StackOverflow issues mention quiver, but unless you need it for some other features you don't have to add another extra package dependency to your project. The standard collection package has this IterableZip

String transformation for subject course code for Dart/Flutter

For interaction with an API, I need to pass the course code in <string><space><number> format. For example, MCTE 2333, CCUB 3621, BTE 1021.
Yes, the text part can be 3 or 4 letters.
Most users enter the code without the space, eg: MCTE2333. But that causes error to the API. So how can I add a space between string and numbers so that it follows the correct format.
You can achieve the desired behaviour by using regular expressions:
void main() {
String a = "MCTE2333";
String aStr = a.replaceAll(RegExp(r'[^0-9]'), ''); //extract the number
String bStr = a.replaceAll(RegExp(r'[^A-Za-z]'), ''); //extract the character
print("$bStr $aStr"); //MCTE 2333
}
Note: This will produce the same result, regardless of how many whitespaces your user enters between the characters and numbers.
Try this.You have to give two texfields. One is for name i.e; MCTE and one is for numbers i.e; 1021. (for this textfield you have to change keyboard type only number).
After that you can join those string with space between them and send to your DB.
It's just like hack but it will work.
Scrolling down the course codes list, I noticed some unusual formatting.
Example: TQB 1001E, TQB 1001E etc. (With extra letter at the end)
So, this special format doesn't work with #Jahidul Islam's answer. However, inspired by his answer, I manage to come up with this logic:
var code = "TQB2001M";
var i = course.indexOf(RegExp(r'[^A-Za-z]')); // get the index
var j = course.substring(0, i); // extract the first half
var k = course.substring(i).trim(); // extract the others
var formatted = '$j $k'.toUpperCase(); // combine & capitalize
print(formatted); // TQB 1011M
Works with other formats too. Check out the DartPad here.
Here is the entire logic you need (also works for multiple whitespaces!):
void main() {
String courseCode= "MMM 111";
String parsedCourseCode = "";
if (courseCode.contains(" ")) {
final ensureSingleWhitespace = RegExp(r"(?! )\s+| \s+");
parsedCourseCode = courseCode.split(ensureSingleWhitespace).join(" ");
} else {
final r1 = RegExp(r'[0-9]', caseSensitive: false);
final r2 = RegExp(r'[a-z]', caseSensitive: false);
final letters = courseCode.split(r1);
final numbers = courseCode.split(r2);
parsedCourseCode = "${letters[0].trim()} ${numbers.last}";
}
print(parsedCourseCode);
}
Play around with the input value (courseCode) to test it - also use dart pad if you want. You just have to add this logic to your input value, before submitting / handling the input form of your user :)

How to combine the elements of an arbitrary number of dependent Fluxes?

In the non reactive world the following code snippet is nothing special:
interface Enhancer {
Result enhance(Result result);
}
Result result = Result.empty();
result = fooEnhancer.enhance(result);
result = barEnhancer.enhance(result);
result = bazEnhancer.enhance(result);
There are three different Enhancer implementations taking a Result instance, enhancing it and returning the enhanced result. Let's assume the order of the enhancer calls matters.
Now what if these methods are replaced by reactive variants returning a Flux<Result>? Because the methods depend on the result(s) of the preceding method, we cannot use combineLatest here.
A possible solution could be:
Flux.just(Result.empty())
.switchMap(result -> first(result)
.switchMap(result -> second(result)
.switchMap(result -> third(result))))
.subscribe(result -> doSomethingWith(result));
Note that the switchMap calls are nested. As we are only interested in the final result, we let switchMap switch to the next flux as soon as new events are emitted in preceding fluxes.
Now let's try to do it with a dynamic number of fluxes. Non reactive (without fluxes), this would again be nothing special:
List<Enhancer> enhancers = <ordered list of different Enhancer impls>;
Result result = Result.empty();
for (Enhancer enhancer : enhancers) {
result = enhancer.enhance(result);
}
But how can I generalize the above reactive example with three fluxes to deal with an arbitrary number of fluxes?
I found a solution using recursion:
#FunctionalInterface
interface FluxProvider {
Flux<Result> get(Result result);
}
// recursive method creating the final Flux
private Flux<Result> cascadingSwitchMap(Result input, List<FluxProvider> fluxProviders, int idx) {
if (idx < fluxProviders.size()) {
return fluxProviders.get(idx).get(input).switchMap(result -> cascadingSwitchMap(result, fluxProviders, idx + 1));
}
return Flux.just(input);
}
// code using the recursive method
List<FluxProvider> fluxProviders = new ArrayList<>();
fluxProviders.add(fooEnhancer::enhance);
fluxProviders.add(barEnhancer::enhance);
fluxProviders.add(bazEnhancer::enhance);
cascadingSwitchMap(Result.empty(), fluxProviders, 0)
.subscribe(result -> doSomethingWith(result));
But maybe there is a more elegant solution using an operator/feature of project-reactor. Does anybody know such a feature? In fact, the requirement doesn't seem to be such an unusual one, is it?
switchMap feels inappropriate here. If you have a List<Enhancer> by the time the Flux pipeline is declared, why not apply a logic close to what you had in imperative style:
List<Enhancer> enhancers = <ordered list of different Enhancer impls>;
Mono<Result> resultMono = Mono.just(Result.empty)
for (Enhancer enhancer : enhancers) {
resultMono = resultMono.map(enhancer::enhance); //previousValue -> enhancer.enhance(previousValue)
}
return resultMono;
That can even be performed later at subscription time for even more dynamic resolution of the enhancers by wrapping the whole code above in a Mono.defer(() -> {...}) block.

What is the better way to do the below program(c#3.0)

Consider the below program
private static bool CheckFactorPresent(List<FactorReturn> factorReturnCol)
{
bool IsPresent = true;
StringBuilder sb = new StringBuilder();
//Get the exposure names from Exposure list.
//Since this will remain same , so it has been done outside the loop
List<string> lstExposureName = (from item in Exposures
select item.ExposureName).ToList<string>();
foreach (FactorReturn fr in factorReturnCol)
{
//Build the factor names from the ReturnCollection dictionary
List<string> lstFactorNames = fr.ReturnCollection.Keys.ToList<string>();
//Check if all the Factor Names are present in ExposureName list
List<string> result = lstFactorNames.Except(lstExposureName).ToList();
if (result.Count() > 0)
{
result.ForEach(i =>
{
IsPresent = false;
sb.AppendLine("Factor" + i + "is not present for week no: " + fr.WeekNo.ToString());
});
}
}
return IsPresent;
}
Basically I am checking if all the FactorNames[lstFactorNames] are present in
ExposureNames[lstExposureName] list by using lstFactorNames.Except(lstExposureName).
And then by using the Count() function(if count() > 0), I am writing the error
messages to the String Builder(sb)
I am sure that someone can definitely write a better implementation than the one presented.
And I am looking forward for the same to learn something new from that program.
I am using c#3.0 and dotnet framework 3.5
Thanks
Save for some naming convention issues, I'd say that looks fine (for what I can figure out without seeing the rest of the code, or the purpose in the effort. The naming conventions though, need some work. A sporadic mix of ntnHungarian, PascalCase, camelCase, and abbrv is a little disorienting. Try just naming your local variables camelCase exclusively and things will look a lot better. Best of luck to you - things are looking good so far!
- EDIT -
Also, you can clean up the iteration at the end by just running a simple foreach:
...
foreach (var except in result)
{
isPresent = false;
builder.AppendFormat("Factor{0} is not present for week no: {1}\r\n", except, fr.WeekNo);
}
...