I want to apply dynamic formula using query string for Map - flutter

I want to add calculation on Map dynamically using query string, as shown below. I will define variable:
Map<dynamic, dynamic> data= new Map();
data["qty"] = 12;
data["price"] = 18;
I want to write just like a string query like below
string string = "Content data["amount"] = data["qty"]*data["price"]";
I want to execute this string and it return Map values which I will add to data map code here, it is possible in flutter.

You can use this package
Math_expressions
And solve math expressions using string like the following
Parser p = Parser();
Expression exp = p.parse("(x^2 + cos(y)) / 3");

Related

How can i convert 'X' to '*' and them compute it in dart

i am building a calculator app although its working fine but i just want to make it look like this before its is been turn into mathematical expression:
how do i achieve something like this:
'5X4' = 20
instead of using the asterisk sign '5*4' = 20
like i want to be able to replace the string 'X' in background before it's been computed
i tried this code below:
final multiply = '5X4';
final computed = multiply.replaceAll('X','*');
final result = computed;
if i run the
print(result)
but if i try
print(int.parse(result));
the console print out
Uncaught Error: FormatException: 5*4
how do i fix this?
You can use expressions package. Here is an example:
String data = "12x2÷3-2+4";
data = data.replaceAll("x", "*");
data = data.replaceAll("÷", "/");
Expression expression = Expression.parse(data);
const evaluator = ExpressionEvaluator();
var r = evaluator.eval(expression, {});
print(r.toString()); // 10.0
You should try this approach.
final multiply = '5X4';
final computed = multiply.replaceAll('X','*');
final List<String> variable1 = computed.split('*');
final result = int.parse(variable1.first) * int.parse(variable1.last);
final lastResult = '$computed = $result';
print(lastResult);
Dartpad

Flutter & Dart : how to retrive map field data from firestore?

Maps key is dynamic key, so i cant set a class to use fromjson method,
Map<String, double> rating;
i set the data , it working;
data['rating'] = json.encode(this.rating);
i try to get data, not working;
rating = jsonDecode(json['rating']);
igot the error:
Expected a value of type 'Map<String, double>', but got one of type 'String'
how can i get the data as Map ?
json.encode turns it into a string. I believe you actually want to just do
data['rating'] = this.rating;
instead of
data['rating'] = json.encode(this.rating);
here is the solution;
i used this;
data['rating'] = FieldValue.arrayUnion([this.rating]);
instead of
data['rating'] = json.encode(this.rating);
or
data['rating'] = this.rating; //both not working
for getting data; (I don't like this solution, but worked)
var asd = json["rating"] as List;
Map qwee = asd[0];
String rtkey = qwee.keys.toList()[0].toString();
double rtvalue = qwee.values.toList()[0];
rating = {rtkey: rtvalue} ;

How to take an array input from a formfield in flutter?

I want to enter a array like [1,2,3,4,5] in the form field and use that form value as a parameter to bubblesort function to sort the array.How to implement this in flutter?
Keep it simple and just use the builtin json parser.
Like this:
List<int> nbs = List<int>.from(json.decode('[1,2,3,4]'));
Our string:
final hi = "[1,2,3,4,5]";
The regular expression used to remove the square brackets:
final regex = RegExp(r'([\[\]])');
Our string without any brackets after replacing them with nothing:
final justNumbers = hi.replaceAll(regex, ''); // 1,2,3,4,5
Our list of strings by splitting them by commas:
List<String> strings = justNumbers.split(',');
Now we parse our strings into integers (tryParse is used so that it returns null instead of throwing an exception):
List<int> numbers = strings.map((e) => int.tryParse(e)).toList();
Final
void main() {
final hi = "[1,2,3,4,5]";
final regex = RegExp(r'([\[\]])');
final justNumbers = hi.replaceAll(regex, '');
List<String> strings = justNumbers.split(',');
List<int> numbers = strings.map((e) => int.tryParse(e)).toList();
print(numbers);
}

Map<string, string> argument

I'm trying to assign a Map<string, string> argument to double. If that's even what I have to do. I have no idea how to work with this argument type. Here it is:
await sheet.values.map.column(3)
I'm using this to extract column #3 and all its values from a google sheet via gsheets. This is a nightmare to work with... Anybody know if there's another way to call the column? or if there's a way to convert the Map<string, string> to a single string containing only the values in the column ? In this case, they're coordinate values for longitude or latitude. I'm trying to call these values for plotting in Google maps. Here's the rest of my code:
Iterable markers = [];
var latstr = (sheet.values.map.column(3)); //latitude
var lngstr = (sheet.values.map.column(4)); //longitude
List<dynamic> names = [];
List<double> lat = [];
List<double> lng = [];
for (var i = 0; i < 10; i++) {
names.add(latstr);
lat.add(parse(await sheet.values.map.column(3)); //<--- I have no idea what I'm doing here. Trying to convert to double. very confused.
lng.add(await sheet.values.map.column(4));
}
to add to this, here's the full error:
The argument type 'Map<String, String>' can't be assigned to the
parameter type'double'.
here's how i'm pulling from google sheets:
const _spreadsheetId = 'xxxxxxxxxxxxxx';
final gsheets = GSheets(_credentials);
final ss = await gsheets.spreadsheet(_spreadsheetId);
var sheet = await ss.worksheetByTitle('xxxxxxxxxxxx');
As the document says await sheet.values.map.column(4) gives you a Map<String,String>, but lng is List<double>, so only doubles can be added to it but you are trying to asign a Map<String,String> which results in the error,
//try this to map the map into a map of doubles (mapception), if your okey with using Map instead of a list
Map<double,double> m = (await sheet.values.map.column(4)).map((key, value)=> MapEntry(double.parse(key), double.parse(value)));
parse will throw if it encounters a character which is not a digit

Sort/Order an Undetermined Number of Columns (LINQ\Entity Framework)

Need to sort/order a list of data based on an undetermined number of columns (1 or more).
What i'm trying to do is loop through the desired columns and add an OrderBy or ThenBy based on their number to the query'd list, but i'm unsuccessful...
Done this, but it doesn't compile:
var query = GetAllItems(); //returns a IQueriable list of items
//for each selected column
for (int i = 0; i < param.Columns.Length; i++)
{
if (i == 0)
{
query = query.OrderBy(x => x.GetType().GetProperty(param.Columns[i].Name));
}
else
{
//ERROR: IQueriable does not contain a definition for "ThenBy" and no extension method "ThenBy"...
query = query.ThenBy(x => x.GetType().GetProperty(param.Columns[i].Data));
}
}
How can i resolve this issue? Or any alternative to accomplish this requirement?
SOLUTION: #Dave-Kidder's solution is well thought and resolves the compile errors i had. Just one problem, OrderBy only executes (actually sorts the results) after a ToList() cast. This is an issue because i can't convert a ToList back to an IOrderedQueryable.
So, after some research i came across a solution that resolve all my issues.
Microsoft assembly for the .Net 4.0 Dynamic language functionality: https://github.com/kahanu/System.Linq.Dynamic
using System.Linq.Dynamic; //need to install this package
Updated Code:
var query = GetAllItems(); //returns a IQueriable list of items
List<string> orderByColumnList = new List<string>(); //list of columns to sort
for (int i = 0; i < param.Columns.Length; i++)
{
string column = param.Columns[i].Name;
string direction = param.Columns[i].Dir;
//ex.: "columnA ASC"
string orderByColumn = column + " " + direction;
//add column to list
orderByColumnList.Add(orderBy);
}
//convert list to comma delimited string
string orderBy = String.Join(",", orderByColumnList.ToArray());
//sort by all columns, yay! :-D
query.OrderBy(orderBy).ToList();
The problem is that ThenBy is not defined on IQueryable, but on the IOrderedQueryable interface (which is what IQueryable.OrderBy returns). So you need to define a new variable for the IOrderedQueryable in order to do subsequent ThenBy calls. I changed the original code a bit to use System.Data.DataTable (to get a similar structure to your "param" object). The code also assumes that there is at least one column in the DataTable.
// using System.Data.DataTable to provide similar object structure as OP
DataTable param = new DataTable();
IQueryable<DataTable> query = new List<DataTable>().AsQueryable();
// OrderBy returns IOrderedQueryable<TSource>, which is the interface that defines
// "ThenBy" so we need to assign it to a different variable if we wish to make subsequent
// calls to ThenBy
var orderedQuery = query.OrderBy(x => x.GetType().GetProperty(param.Columns[0].ColumnName));
//for each other selected column
for (int i = 1; i < param.Columns.Count; i++)
{
orderedQuery = orderedQuery.ThenBy(x => x.GetType().GetProperty(param.Columns[i].ColumnName));
}
you should write ThenBy after OrderBy like this:
query = query
.OrderBy(t=> // your condition)
.ThenBy(t=> // next condition);