I’m trying to get the variable name instead of the value to pass it to another method
eg.
String myString = "xyz";
String getVariableName(String s){
// What i want is if the above string is passed [getVariableName(myString)]
//i want it to return ['myString']
}
This is generally not possible. At best, if there are a finite number of String variables you care about, you could manually make a collection of them, and then search it:
final stringVariables = <String, String Function()>{
'myString': () => myString,
'myOtherString': () => myOtherString,
};
var myString = 'xyz';
var myOtherString = 'abc';
String getVariableName(String s) {
for (var entry in stringVariables.entries) {
if (entry.value() == s) {
return entry.key;
}
}
return '';
}
void main() {
print(getVariableName('xyz')); // Prints: myString
myString = 'foo';
print(getVariableName('foo')); // Prints: myString
}
Note that stringVariables's above must use a Function as a thunk to delay evaluation of the variable; otherwise the variable name would be associated with whatever value it happened to have when stringVariables is first accessed and wouldn't work if your variables are reassigned.
All that said, I don't really recommend doing any of this. This sounds like an XY problem. You should be asking about whatever it is you ultimately want to do, and there probably is a better way to accomplish that task.
I'm running a Apps Script to create a data entry form. Sometimes my searchRecord function works if I run it several times. Sometimes it doesn't pull any info, but never gives me the warning screen, sometimes it pulls the info from the last search. I'm not sure where the problem is. I have copied the code below.
//Function to Search the record
function searchRecord(){
var myGoogleSheet=SpreadsheetApp.getActiveSpreadsheet(); //declare a variable and set with active Google Sheet
var shUserForm=myGoogleSheet.getSheetByName("User Form"); //declare a variable and set with the User Form reference
var datasheet=myGoogleSheet.getSheetByName("Existing Customers"); //declare variable and set the reference of database sheet
var str=shUserForm.getRange("B2").getValue(); //get data input for search button
var values=datasheet.getDataRange().getValues(); //getting the entire values from the used range and assigning it to values variable
var valuesFound=false; //variable to store boolean value
for (var i=0; i<values.length; i++)
{
var rowValue=values[i]; //declare a variable and storing the value
//checking the first value of the record is equal to search item
if(rowValue[6]==str){
shUserForm.getRange("B12").setValue(rowValue[0]);
shUserForm.getRange("B15").setValue(rowValue[1]);
shUserForm.getRange("B23").setValue(rowValue[2]);
shUserForm.getRange("B17").setValue(rowValue[3]);
shUserForm.getRange("E17").setValue(rowValue[4]);
shUserForm.getRange("B8").setValue(rowValue[6]);
shUserForm.getRange("E8").setValue(rowValue[7]);
shUserForm.getRange("B19").setValue(rowValue[8]);
shUserForm.getRange("E19").setValue(rowValue[9]);
shUserForm.getRange("B21").setValue(rowValue[10]);
shUserForm.getRange("E21").setValue(rowValue[11]);
shUserForm.getRange("E23").setValue(rowValue[12]);
shUserForm.getRange("E12").setValue(rowValue[13]);
shUserForm.getRange("B25").setValue(rowValue[14]);
shUserForm.getRange("E25").setValue(rowValue[15]);
shUserForm.getRange("B27").setValue(rowValue[16]);
shUserForm.getRange("E27").setValue(rowValue[17]);
shUserForm.getRange("B29").setValue(rowValue[18]);
shUserForm.getRange("E29").setValue(rowValue[19]);
shUserForm.getRange("B31").setValue(rowValue[20]);
shUserForm.getRange("E10").setValue(rowValue[21]);
shUserForm.getRange("B33").setValue(rowValue[22]);
shUserForm.getRange("B35").setValue(rowValue[23]);
shUserForm.getRange("B37").setValue(rowValue[24]);
shUserForm.getRange("E31").setValue(rowValue[25]);
shUserForm.getRange("E35").setValue(rowValue[26]);
shUserForm.getRange("B39").setValue(rowValue[27]);
shUserForm.getRange("E39").setValue(rowValue[27]);
shUserForm.getRange("B41").setValue(rowValue[29]);
shUserForm.getRange("E15").setValue(rowValue[30]);
shUserForm.getRange("B43").setValue(rowValue[31]);
shUserForm.getRange("E43").setValue(rowValue[32]);
shUserForm.getRange("B45").setValue(rowValue[33]);
shUserForm.getRange("E45").setValue(rowValue[34]);
shUserForm.getRange("B47").setValue(rowValue[35]);
shUserForm.getRange("B49").setValue(rowValue[36]);
shUserForm.getRange("B10").setValue(rowValue[37]);
shUserForm.getRange("E37").setValue(rowValue[5]);
valuesFound=true;
return;//come out from the loop
}
if(valuesFound=false){
//to create the instance of the user-interface environment to use the alert function
var ui=SpreadsheetApp.getui();
ui.alert("No Record Found");}
}
}
Solution
There are different points in your code that could be improved, I attach the updated function correcting the basics:
Indentation: This is easy to fix, just press ctrl + shft + i to correctly indent the code.
Break statement: Use the word break to break a loop.
Wrong comparison operator: The second if has only one = instead of two ==. Check Expressions and operators
Structural logic: Inside the for loop there are two ifs. Only the second one depends on the value of the valuesFound variable, which when modified breaks the loop, so it is not really doing anything.
Readability: It is difficult to understand what the code is doing and so many setValue boxes with no apparent connection is confusing.
In addition, it is difficult to offer help if the behavior of the function is variable and the reason is not known. Apparently, it should always give the same result.
Updated code
function searchRecord() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); //declare a variable and set with active Google Sheet
var shUserForm = ss.getSheetByName("User Form"); //declare a variable and set with the User Form reference
var datasheet = ss.getSheetByName("Existing Customers"); //declare variable and set the reference of database sheet
var str = shUserForm.getRange("B2").getValue(); //get data input for search button
var values = datasheet.getDataRange().getValues(); //getting the entire values from the used range and assigning it to values variable
var valuesFound = false; //variable to store boolean value
var ui = SpreadsheetApp.getui();
for (var i = 0; i < values.length; i++) {
var rowValue = values[i]; //declare a variable and storing the value
//checking the first value of the record is equal to search item
if (rowValue[6] == str) {
shUserForm.getRange("B12").setValue(rowValue[0]);
shUserForm.getRange("B15").setValue(rowValue[1]);
shUserForm.getRange("B23").setValue(rowValue[2]);
shUserForm.getRange("B17").setValue(rowValue[3]);
shUserForm.getRange("E17").setValue(rowValue[4]);
shUserForm.getRange("B8").setValue(rowValue[6]);
shUserForm.getRange("E8").setValue(rowValue[7]);
shUserForm.getRange("B19").setValue(rowValue[8]);
shUserForm.getRange("E19").setValue(rowValue[9]);
shUserForm.getRange("B21").setValue(rowValue[10]);
shUserForm.getRange("E21").setValue(rowValue[11]);
shUserForm.getRange("E23").setValue(rowValue[12]);
shUserForm.getRange("E12").setValue(rowValue[13]);
shUserForm.getRange("B25").setValue(rowValue[14]);
shUserForm.getRange("E25").setValue(rowValue[15]);
shUserForm.getRange("B27").setValue(rowValue[16]);
shUserForm.getRange("E27").setValue(rowValue[17]);
shUserForm.getRange("B29").setValue(rowValue[18]);
shUserForm.getRange("E29").setValue(rowValue[19]);
shUserForm.getRange("B31").setValue(rowValue[20]);
shUserForm.getRange("E10").setValue(rowValue[21]);
shUserForm.getRange("B33").setValue(rowValue[22]);
shUserForm.getRange("B35").setValue(rowValue[23]);
shUserForm.getRange("B37").setValue(rowValue[24]);
shUserForm.getRange("E31").setValue(rowValue[25]);
shUserForm.getRange("E35").setValue(rowValue[26]);
shUserForm.getRange("B39").setValue(rowValue[27]);
shUserForm.getRange("E39").setValue(rowValue[27]);
shUserForm.getRange("B41").setValue(rowValue[29]);
shUserForm.getRange("E15").setValue(rowValue[30]);
shUserForm.getRange("B43").setValue(rowValue[31]);
shUserForm.getRange("E43").setValue(rowValue[32]);
shUserForm.getRange("B45").setValue(rowValue[33]);
shUserForm.getRange("E45").setValue(rowValue[34]);
shUserForm.getRange("B47").setValue(rowValue[35]);
shUserForm.getRange("B49").setValue(rowValue[36]);
shUserForm.getRange("B10").setValue(rowValue[37]);
shUserForm.getRange("E37").setValue(rowValue[5]);
valuesFound = true;
break
}
if (valuesFound == false) {
//to create the instance of the user-interface environment to use the alert function
ui.alert("No Record Found");
}
}
}
I have an array defined using RxSwift as
public var calendarNDays = BehaviorRelay<[CalendarControlDayModel]>(value: [])
CalendarControlDayModel is a structure as below.
struct CalendarControlDayModel {
var date: String = ""
var day: Int = 0
var name: String = ""
}
Once the calendarNDays is updated with elements at some point of time I want to modify the name property of i-th element in the array.
Like self.calendarNDays.value[i].name = "Nancy". However, I get the compilation error "Cannot assign to property: 'value' is a get-only property".
What is the way to modify a particular property of an element in a behaviour relay array?
As the compiler suggests the value in BehaviorRelay is a read-only property.
Therefore in order to make changes to the array you first need to copy it and use the accept method to reflect the changes.
Similar to
var update = calendarNDays.value
update[i].name = “Nancy”
calendarNDays.accept(update)
How to select random key (element) from Map?
I can do it using map.keys.toList(), as in the code below, but I wonder if there is more direct way?
import "dart:math";
void main() {
var map = {'a' :1, 'b':2, 'c':3};
final _random = new Random();
var keys = map.keys.toList();
var element = keys[_random.nextInt(keys.length)];
var r = map[element];
print(r);
}
There is no simple way to pick a "random" key from a map.
I assume that "random" here means to pick it uniformly at random among the keys of the map.
For that, you need to pick a random number in the range 0..map.length - 1. Then you need to get the corresponding key. Since Map.key is an iterable, you can't assume that you can do constant-time lookup in it, but you can use elementAt to get a specific iterable item without creating a new list.
So, basically:
randomKey(Map map) =>
map.keys.elementAt(new Random().nextInt(map.length));
(like you do it, but without the toList).
If you need more than one key, you are probably better off converting the keys to a list once, and then do lookups in the list in constant time. Example:
Iterable randomKeys(Map map) sync* {
var keys = map.keys.toList();
var rnd = new Random();
while (keys.length > 0) {
var index = rnd.nextInt(keys.length);
var key = keys[index];
keys[index] = keys.last;
keys.length--;
yield key;
}
}
On top of getting better performance, taking a copy of the keys also avoids concurrent modification errors.
If you are selecting multiple random values from the list and you want to make sure you never select an entry more than once, you can take the keys or values as a list, shuffle it then iterate through it.
This is not very efficient if only a small fraction of the entries in the map are to be selected.
void main() {
var map = { 'a' :1, 'b':2, 'c':3 };
// Keys
var keys = map.keys.toList()..shuffle();
for(var k in keys) {
print('$k, ${map[k]}');
}
// Values
var values = map.values.toList()..shuffle();
for(var v in values) {
print(v);
}
}
https://dartpad.dartlang.org/e49012d93f7451af1662ad113f0aab95
I guess this is not what you're looking for, but actually it's a line shorter ;-)
void main() {
var map = {'a' :1, 'b':2, 'c':3};
final _random = new Random();
var values = map.values.toList();
var element = values[_random.nextInt(values.length)];
print(element);
}
DartPad example
You can use the dart_random_choice package to help you. While Map itself is not an iterable, you can use the Map.keys method to get an iterable and do the following:
import 'package:dart_random_choice/dart_random_choice.dart';
void main() {
var map = { 'a': 1, 'b': 2, 'c':3 };
var r = map[randomChoice(map.keys)];
print(r);
}
According to this article:
As you might know, dynamic (as it is now called) is the stand-in type when a static type annotation is not provided.
So, what is the difference between dynamic and var? When to use?
dynamic is a type underlying all Dart objects. You shouldn't need to explicitly use it in most cases.
var is a keyword, meaning "I don't care to notate what the type is here." Dart will replace the var keyword with the initializer type, or leave it dynamic by default if there is no initializer.
Use var if you expect a variable assignment to change during its lifetime:
var msg = "Hello world.";
msg = "Hello world again.";
Use final if you expect a variable assignment to remain the same during its lifetime:
final msg = "Hello world.";
Using final (liberally) will help you catch situations where you accidentally change the assignment of a variable when you didn't mean to.
Note that there is a fine distinction between final and const when it comes to objects. final does not necessarily make the object itself immutable, whereas const does:
// can add/remove from this list, but cannot assign a new list to fruit.
final fruit = ["apple", "pear", "orange"];
fruit.add("grape");
// cannot mutate the list or assign a new list to cars.
final cars = const ["Honda", "Toyota", "Ford"];
// const requires a constant assignment, whereas final will accept both:
const names = const ["John", "Jane", "Jack"];
dynamic: can change TYPE of the variable, & can change VALUE of the variable later in code.
var: can't change TYPE of the variable, but can change VALUE of the variable later in code.
final: can't change TYPE of the variable, & can't change VALUE of the variable later in code.
dynamic v = 123; // v is of type int.
v = 456; // changing value of v from 123 to 456.
v = 'abc'; // changing type of v from int to String.
var v = 123; // v is of type int.
v = 456; // changing value of v from 123 to 456.
v = 'abc'; // ERROR: can't change type of v from int to String.
final v = 123; // v is of type int.
v = 456; // ERROR: can't change value of v from 123 to 456.
v = 'abc'; // ERROR: can't change type of v from int to String.
try this in DartPad:
void main() {
dynamic x = 'hal';
x = 123;
print(x);
var a = 'hal';
a = 123;
print(a);
}
you can change the type of x, but not a.
var, like final, is used to declare a variable. It is not a type at all.
Dart is smart enough to know the exact type in most situations. For example, the following two statements are equivalent:
String a = "abc"; // type of variable is String
var a = "abc"; // a simple and equivalent (and also recommended) way
// to declare a variable for string types
On the other hand, dynamic is a special type indicating it can be any type (aka class). For example, by casting an object to dynamic, you can invoke any method (assuming there is one).
(foo as dynamic).whatever(); //valid. compiler won't check if whatever() exists
(foo as var).whatever(); //illegal. var is not a type
var a ;
a = 123;
print(a is int);
print(a);
a = 'hal';
print(a is String);
When defined without initial value, var is dynamic
var b = 321;
print(b is int);
print(b);
//b = 'hal'; //error
print(b is String);
When defined with initial value, var is int in this case.
To clarify some of the previous answers, when you're declaring a variable as dynamic, it's type changes depending on what you assign to it. When you're declaring a var, the type is set once it's assigned something, and it cannot be changed after that.
For example, the following code:
dynamic foo = 'foo';
print('foo is ${foo.runtimeType} ($foo)');
foo = 123;
print('foo is ${foo.runtimeType} ($foo)');
will return the following result when run in DartPad:
foo is String (foo)
foo is int (123)
But the following code won't even compile:
var bar = 'bar';
print('bar is ${bar.runtimeType} ($bar)');
bar = 123; // <-- Won't compile, because bar is a String
print('bar is ${bar.runtimeType} ($bar)');
Long story short - use dynamic if you want a non-typed variable, use var when you want a typed variable with whatever type you assign to it.
Looking at the previous answers I hope this can clarify/summarize everything:
There are the keywords var, final, and const. These are to declare a variable (to indicate its existence) (Side note: Declaration vs Initialization)
Then there are types like String, int, List, dynamic, etc. (The type indicates what kind of value the variable should hold, this is for type safety)
Usually, we declare a variable by explicitly stating its type:
String a; // a is now a String type
int b; // b is now an int type
But we can also use the var keyword. By default, this sets the type of the variable to whatever it is initialized with. (This is called type inference)
var a = "hello"; // a is now a String type
var b = 5; // b is now an int type
Now what happens when you try to declare a variable with the var keyword, but don't initialize a value? How is it supposed to infer a type? Well, there is also a type called dynamic. This is different than the usual String or int in the sense that it allows for the variable to be assigned a value of any type (Usually there will be an error).
String a = "hello"; // a is now a String type
// var a = "hello"; // Alternative way; same as the line above because its type is inferred to be String
a = 5 // error: A value of type 'int' can't be assigned to a variable of type 'String'
dynamic b; // b is now a dynamic type
b = "hello"; // still a dynamic type, but now its value is of type String (You can use b.runtimeType to check)
b = 5; // dynamic type, but now its value is of type int
So to address the original confusion regarding the quote from the article,
As you might know, dynamic (as it is now called) is the stand-in type when a static type annotation is not provided.
It just means that if you don't explicitly state its type (you use var to declare a variable) and do so without initialization, it simply infers its type as dynamic:
var b; // b is now a dynamic type, the following will not have any errors.
b = "hello";
b = 5;
b = true;
Other notes:
Not sure why people started talking about final and const, but I think the accepted answer here explains it well if you want to know more.
dynamic a; and var a; is effectively the same: They both declare a variable of dynamic type.
Two ways of checking the type of a variable is using the is operator and using .runtimeType which works differently. See the following example:
dynamic b; // b is now a dynamic type, no value
print(b is dynamic); // true
print(b is Null); // true
print(b is String); // false
print(b is int); // false
print(b.runtimeType); // Null
b = "hello"; // dynamic type, String value
print(b is dynamic); // true
print(b is Null); // false
print(b is String); // true
print(b is int); // false
print(b.runtimeType); // String
b = 5; // dynamic type, int value
print(b is dynamic); // true
print(b is Null); // false
print(b is String); // false
print(b is int); // true
print(b.runtimeType); // int
One of aspect than can consider in comparison dynamic vs var is taking into account behavior when using var declaration with initialization at the same time there is not possibility to change type which in case of dynamic is.
But dynamic vs var is not the question what I would ask.
I would ask more what is difference between dynamic vs Object.
Here is a DO annotate with Object instead of dynamic to indicate any object is allowed.
It is hard to feel it at the beginning, but dynamic I would relate to generic type argument.
Both in dynamic and var,the variable can hold data of any data type, i.e., int , float,string,etc
If a variable is declared as a dynamic and if even initialised, its type can change over time.Try this code in https://dartpad.dev/
void main() {
dynamic x = 'abc';
x = 12345;
print(x);
}
If you declare variable as a var, once assigned type can not change.
void main() {
var x = 'abc';
x = 12345;
print(x);
}
The above code will result in the error stating that A value of type 'int' can't be assigned to a variable of type 'String' - line 3
BUT, if you state a var without initializing, it becomes a dynamic:
void main() {
var x ;
x = 'abc';
x=12345;
print(x);
}
A dynamic variable can change his type and a var type can't be changed.
For example :
var myVar = 'hello';
dynamic myDynamicVar = 'hello';
myVar = 123; // not possible
myDynamicVar = 123; // possible
dynamic is a data type that indicates all data types in dart
var is a variable declaration way like "final" that takes the data type of its value
If you use var you can't change the data type of the variable. But if you use dynamic you can change it freely.
for ex.
dynamic x = 12; // type: integer
x= "Hello world"; // type: string
This will work with no issues if you do the same using var instead of dynamic you will get an error since you can't change the data type because it is automatically assigned to the variable when initialized.
dynamic: can change the TYPE of the variable, & can change the VALUE of the variable later in the code.
var: can't change the TYPE of the variable, but can change the VALUE of the variable later in code