I know how to print map using foreach() method
var x = {1:'One',2:'Two',3:'Three',4:'Four',5:'Five'};
x.foreach((i,j){
print(i);
print(j);
});
and using normal for loop
other methods to print map ?
You can also directly print the map:
void main() {
var x = {1:'One',2:'Two',3:'Three',4:'Four',5:'Five'};
print(x);
}
The result will be pretty neat:
{1: One, 2: Two, 3: Three, 4: Four, 5: Five}
You will find the implementation of mapToString here.
static String mapToString(Map<Object?, Object?> m) {
// Reuses the list in IterableBase for detecting toString cycles.
if (_isToStringVisiting(m)) {
return '{...}';
}
var result = StringBuffer();
try {
_toStringVisiting.add(m);
result.write('{');
bool first = true;
m.forEach((Object? k, Object? v) {
if (!first) {
result.write(', ');
}
first = false;
result.write(k);
result.write(': ');
result.write(v);
});
result.write('}');
} finally {
assert(identical(_toStringVisiting.last, m));
_toStringVisiting.removeLast();
}
return result.toString();
}
Related
This is the question of Binary Tree. Level: Easy
In the second code, in while loop I just stored the value of popped integer value from stack in int variables and then wrote the condition of if loop. But in first I did not stored them in any variables I directly used them in if condition of while loop. Can anyone please explain why is it creating a difference?
This was my approach, in this if the input trees are 333 and 333 then it gives "no"(trees are not identical).
`
class Solution
{
public void preOrder(Node root,Stack<Integer> stack){
if(root==null){
return ;
}
stack.push(root.data);
preOrder(root.left,stack);
preOrder(root.right,stack);
}
boolean isIdentical(Node root1, Node root2)
{
// Code Here
if(root1==null||root2==null)
return false;
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
preOrder(root1,stack1);
preOrder(root2,stack2);
if(stack1.size()!=stack2.size())
return false;
while(!stack1.isEmpty()&&!stack2.isEmpty()){
if(stack1.pop()!=stack2.pop())
return false;
}
return true;
}
}`
But, in this the same input trees(333 and 333) gave correct output i.e "yes".
` class Solution
{
public void preOrder(Node root,Stack<Integer> stack){
if(root==null){
return ;
}
stack.push(root.data);
preOrder(root.left,stack);
preOrder(root.right,stack);
}
boolean isIdentical(Node root1, Node root2)
{
// Code Here
if(root1==null||root2==null)
return false;
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
preOrder(root1,stack1);
preOrder(root2,stack2);
if(stack1.size()!=stack2.size())
return false;
while(!stack1.isEmpty()&&!stack2.isEmpty()){
int n1 = stack1.pop();
int n2 = stack2.pop();
if(n1!=n2)
return false;
}
return true;
}
}`
The listener function can listen to any parameter type(not only listener type). This has nothing related to widgets (this should work successfully in https://dartpad.dev without using the flutter).
ex.
int a = 0;
listener((a>0)=>print("A = $a"));
a= 1; //A = 1
a= -1; //
a= 2; //A = 2
You can use ValueNotifier for this. It's a ChangeNotifier that is triggered when the value is replaced with something that is not equal to the old value as evaluated by the equality operator ==.
Here is a nice tutorial about this approach.
The basic method is to create the function for updating the parameter that you want to add to the listener.
void test() {
int a = 0;
void updateA(newA) {
if(newA is! int) return;
a = newA;
if (a > 0) print("A = $a");
}
updateA(1);
updateA(-1);
updateA(2);
}
A better way is to create parameters with class.
void main() {
ParameterWithListener a = ParameterWithListener(data: 0);
a.listener = () {
if (a.data is int && a.data > 0) print("A = ${a.data}");
};
a.update(1);
a.update(-1);
a.update(2);
}
class ParameterWithListener {
ParameterWithListener({this.data, this.listener});
dynamic data;
Function()? listener;
Future update(data) async {
this.data = data;
if (listener is Function()) await listener!();
}
}
result:
A = 1
A = 2
I want to create a map using the path
generateNestedMap("foo.bar.baz", "someValue")
and the output should be
Output: {'foo'{'bar':{'baz': 'someValue'}}}
Run this in dartpad. No recursion required. Just build it from inside-out:
void main() {
print(generateNestedMap("foo.bar.baz", "someValue"));
}
Map generateNestedMap(String path, String payload) {
var steps = path.split('.');
Object result = payload;
for (var step in steps.reversed) {
result = {step : result};
}
return result as Map;
}
EDIT: Or, as I suggested in one of the comments, a little fancier, but cool:
void main() {
print(generateNestedMap("foo.bar.baz", "someValue"));
}
Map generateNestedMap(String path, String payload) {
var steps = path.split('.');
var result = steps.reversed.fold(payload, (old, next) => {next: old});
return result as Map;
}
Lets say you are trying to access deeply nested children in a map and you are not able to expect their parents to be there. Example:
Map awesomeMap = {
"this":{
"is":{
"sometimes":"not here"
}
}
}
Map notAwesomeMap = {
"this":{
"haha":{
"we":"switched"
}
}
}
When I go to access notAwesomeMap['this']['is']['sometimes'] it will return an error because ['this']['is'] is null, and you cannot look for the value ['sometimes'] of null.
So that's fine, but I was hoping to be able to use conditional member access operators...
notAwesomeMap['this']?.['is']?.['sometimes']
but that doesn't work...
Short of wrapping everything in a try block, is there a good way to handle these situations?
Edit: I tried playing around with this and I didn't find anything really illuminating, but maybe this gives someone an idea
void main() {
Map nestedMap = {
'this':{
'is':{
'sometimes':'here'
}
}
};
final mapResult = nestedMap['this'];
print(mapResult); //returns {is: {sometimes: here}}
final nullResult = nestedMap['this']['is an'];
print(nullResult); // returns null
final nullifiedResult = nullify(nestedMap['this']['is an']['error']);
print(nullifiedResult); // returns error, but is this possible another way?
final errorResult = nestedMap['this']['is an']['error'];
print(errorResult); // returns error
}
nullify(object){
try {
final result = object;
return result;
}
catch (e) {
return null;
}
}
One way would be
final result = (((nestedMap ?? const {})['this'] ?? const {})['is an'] ?? const {})['error'];
See also Null-aware operator with Maps
You could write a simple function to help do what you want:
R lookup<R, K>(Map<K, dynamic> map, Iterable<K> keys, [R defaultTo]);
Example usage:
final result = lookup(inputMap, ['this', 'is', 'something']);
Example implementation:
https://dartpad.dartlang.org/1a937b2d8cdde68e6d6f14d216e4c291
void main() {
var nestedMap = {
'this':{
'is':{
'sometimes':'here'
}
}
};
print(lookup(nestedMap, ['this']));
print(lookup(nestedMap, ['this', 'is']));
print(lookup(nestedMap, ['this', 'is', 'sometimes']));
print(lookup(nestedMap, ['this', 'is', 'error']));
// Bail out on null:
print(lookup(nestedMap, ['error'], 'Default Value'));
}
R lookup<R, K>(Map<K, dynamic> map, Iterable<K> keys, [R defaultTo]) {
dynamic current = map;
for (final key in keys) {
if (current is Map<K, dynamic>) {
current = current[key];
} else {
return defaultTo;
}
}
return current as R;
}
I like #matanlurey's approach, but have made two changes:
Drop the defaultTo since you can still use ?? which is more readable.
Swallow type-cast errors.
R lookup <R, K>(Map<K, dynamic> map, Iterable<K> keys) {
dynamic current = map;
for (final key in keys) {
if (current is Map<K, dynamic>) {
current = current[key];
}
}
try{
return current as R;
} catch(e){
// do nothing
}
}
Usage is similar
String someValue = lookup(nestedMap, ['some', 'value']) ?? 'Default Value';
Does Dart support the concept of variable functions/methods? So to call a method by its name stored in a variable.
For example in PHP this can be done not only for methods:
// With functions...
function foo()
{
echo 'Running foo...';
}
$function = 'foo';
$function();
// With classes...
public static function factory($view)
{
$class = 'View_' . ucfirst($view);
return new $class();
}
I did not found it in the language tour or API. Are others ways to do something like this?
To store the name of a function in variable and call it later you will have to wait until reflection arrives in Dart (or get creative with noSuchMethod). You can however store functions directly in variables like in JavaScript
main() {
var f = (String s) => print(s);
f("hello world");
}
and even inline them, which come in handy if you are doing recusion:
main() {
g(int i) {
if(i > 0) {
print("$i is larger than zero");
g(i-1);
} else {
print("zero or negative");
}
}
g(10);
}
The functions stored can then be passed around to other functions
main() {
var function;
function = (String s) => print(s);
doWork(function);
}
doWork(f(String s)) {
f("hello world");
}
I may not be the best explainer but you may consider this example to have a wider scope of the assigning functions to a variable and also using a closure function as a parameter of a function.
void main() {
// a closure function assigned to a variable.
var fun = (int) => (int * 2);
// a variable which is assigned with the function which is written below
var newFuncResult = newFunc(9, fun);
print(x); // Output: 27
}
//Below is a function with two parameter (1st one as int) (2nd as a closure function)
int newFunc(int a, fun) {
int x = a;
int y = fun(x);
return x + y;
}