https://dartpad.dev/?
import 'package:starter/stack.dart';
void main() {
print (calculation("(2+2*6"));
}
calculation(expression){
var tokens = expression.split(" ");
Stack values = Stack();
Stack ops = Stack();
}
note that if I remove the import (first line) I get this error message "The function 'Stack' isn't defined."
and when I add the import the error message is "Unsupported import(s): (package:starter/stack.dart)".
Stack is not built in the dart. But we can make a generic class with its methods(get, push, pop) implementation using list.
class CustomStack<T> {
final _list = <T>[];
void push(T value) => _list.add(value);
T pop() => _list.removeLast();
T get top => _list.last;
bool get isEmpty => _list.isEmpty;
bool get isNotEmpty => _list.isNotEmpty;
#override
String toString() => _list.toString();
}
Just put the above class somewhere in the project lib directory.
And use it like.
CustomStack<String> plates = CustomStack();
//Add plates into the stack
plates.push("Plate1");
plates.push("Plate2");
plates.push("Plate3");
// delete the top plate
plates.pop();
Related
class CustomStack<T> {
final _list = <T>[];
void push(T value) => _list.add(value);
T pop() => _list.removeLast();
T get top => _list.last;
bool get isEmpty => _list.isEmpty;
bool get isNotEmpty => _list.isNotEmpty;
int get length => _list.length;
#override
String toString() => _list.toString();
}
void main() {
CustomStack<String> plates = CustomStack();
//Add plates into the stack
plates.push("Plate1");
plates.push("Plate2");
plates.push("Plate3");
plates.push("Plate Extra");
print(plates);
print(plates[plates.length-1]);
}
I get an error in the last line "The operator '[]' isn't defined for the type 'CustomStack'."
How can I control the index in the stack.
I want to print only "Plate Extra" on the screen.
There is no need to use that structure plates[plates.length-1] if getting the last element is possible with the built function. If you want to get the last item in Custom Stack, you can define a function in your Custom Stack.
T get peek => _list.last;
I've got a global list like this:
var data = [1,2,3];
I will add more elements to it, and each time I do I want something else to be notified - I need a stream and listener. So can I make a stream and tell it to run sink.add anytime the list mutates?
var stream = Stream.fromIterable(data);
stream.listen((item) => print(item));
> 1
> 2
> 3
data.add(4);
> Uncaught Error: Concurrent modification during iteration
data.remove(3);
> Uncaught Error: Concurrent modification during iteration
Oh no. What can I do to make this work?
This might help:
import 'dart:async';
class ObservableList<T> {
final _list = <T>[];
final _itemAddedStreamController = StreamController<T>();
final _listStreamController = StreamController<List<T>>();
Stream get itemAddedStream => _itemAddedStreamController.stream;
Stream get listStream => _listStreamController.stream;
void add(T value) {
_list.add(value);
_itemAddedStreamController.add(value);
_listStreamController.add(_list);
}
void dispose() {
_listStreamController.close();
_itemAddedStreamController.close();
}
}
void main() {
final observableList = ObservableList<int>();
observableList.itemAddedStream.listen((value) => print(value));
observableList.add(1);
observableList.add(2);
observableList.add(3);
observableList.add(4);
}
I'm looking at some Flutter code that looks like this :
try {
return Right(_doSomethingAndReturnSingleValue());
} on CustomException {
return Left(CustomException());
}
Left and Right are from the core either.dart package, this is the code :
class Left<L, R> extends Either<L, R> {
final L _l;
const Left(this._l);
L get value => _l;
#override B fold<B>(B ifLeft(L l), B ifRight(R r)) => ifLeft(_l);
#override bool operator ==(other) => other is Left && other._l == _l;
#override int get hashCode => _l.hashCode;
}
class Right<L, R> extends Either<L, R> {
final R _r;
const Right(this._r);
R get value => _r;
#override B fold<B>(B ifLeft(L l), B ifRight(R r)) => ifRight(_r);
#override bool operator ==(other) => other is Right && other._r == _r;
#override int get hashCode => _r.hashCode;
}
I'm really struggling to make any sense of what this logic is supposed to do.
Can anyone help me understand what Left() and Right() are for in Dart ?
Left and Right are two generic classes inherited from the same parent, which does almost same thing. The major difference is in the fold method implementation. The left class call the ifLeft callback and right class call the ifRight callback.
For example:
Either<CustomException, String> getSomething() {
try {
return Right(_doSomethingAndReturnSingleValue());
} on CustomException {
return Left(CustomException());
}
}
No matter what happens the above function will return either an object of Either with CustomException (Means Left) or an object of Either with String (Means Right).
Now if you use the function like:
final eitherData = getSomething();
You will be getting an either object (Object of Left or Right). Instead of checking whether that eitherData is of type Left or Right, you can call the fold method on that object like below:
eitherData.fold<Widget>(
(err) => Text('Error Happened: $err'), // ifLeft callback
(data) => Text('Got data: $data'), // ifRight callback
)
As I mentioned earlier based on the object type the corresponding callback will get triggered and you can gracefully handle the success and error cases without writing any if else statements or type checks.
In java it would be something like this ...
public Request compose(LoginDevice login) {
JSONObject params = new JSONObject();
try {
if (login.granType != null)
params.put("grant_type", login.granType);
if (login.clientId != null)
params.put("client_id", login.clientId);
} catch (JSONException e) {
e.printStackTrace();
}
return (Request)new BaseRequest("oauth/v2/token", params.toString(), new HashSet());
}
And in Dart and tried something similar but it doesn't work... the parameter 'put' does not exist in JsonObjectLite...
Request compose(LoginDevice login)
{
JsonObjectLite params = new JsonObjectLite();
try {
if (login.granType != null) {
params.put("grant_type", login.granType);
}
if (login.clientId != null) {
params.put("client_id", login.clientId);
}
} on JsonObjectLiteException catch (e) {
print(e);
}
return new BaseRequest("oauth/v2/token", params.toString(), new HashSet());
}
How could I do it? Thank you
The class JsonObjectLite doesn't contain the method put.
How you can understand dart doesn't is Java, in this cases your the class JsonObjectLite has a method called putIfAbsent, the implementation is the following
/// If [isImmutable] is false, or the key already exists,
/// then allow the edit.
/// Throw [JsonObjectLiteException] if we're not allowed to add a new
/// key
#override
void putIfAbsent(dynamic key, Function() ifAbsent) {
if (isImmutable == false || containsKey(key)) {
_objectData.putIfAbsent(key, ifAbsent);
} else {
throw const JsonObjectLiteException('JsonObject is not extendable');
}
}
look also the Source code
So an example of code should be the following
import 'package:json_object_lite/json_object_lite.dart';
class AuthorAnswer {
var _username;
var _status;
AuthorAnswer(this._username, this._status);
String get username => _username;
String get status => _status;
}
int main() {
var author = '#vincenzopalazzo';
var sentences = 'Follow me on Github';
var authorObject = AuthorAnswer(author, sentences);
try{
JsonObjectLite params = new JsonObjectLite();
params.isImmutable = false;
params.putIfAbsent("author", () => authorObject.username);
params.putIfAbsent("sencence", () => authorObject.status);
print(params.toString());
} on JsonObjectLiteException catch (err){
print('--------- ERROR ----------');
print(err);
}
return 0;
}
You should be set the params.isImmutable = false and after you can add your propriety, with your logic.
In my opinion, I don't see any motivation to use this library, dart have 2 types of the module to implement the serialization, and I think should better use it because on the web exist the documentation, like this dart json, flutter json
Inside the flutter app, there are also the line guides, for the small application you can use dart:convert:json also for the other you can use the json_serializable
I want to add also an example of dart:convert
/**
*
*/
import "dart:core";
import "dart:convert";
class ClassToJsonOne {
var _propOne;
var _propTwo;
ClassToJsonOne(this._propOne, this._propTwo);
Map<String, dynamic> toJSon() => {
'prop_one': _propOne,
'prop_two': _propTwo
};
ClassToJsonOne.fromJson(Map<String, dynamic> json):
_propOne = json['prop_one'],
_propTwo = json['prop_two'];
#override
String toString() => 'First Class: $_propOne, $_propTwo';
}
class ClassToJsonTwo{
var _propOne;
var _propTwo;
ClassToJsonTwo(this._propOne, this._propTwo);
Map<String, dynamic> toJSon() => {
'prop_one': _propOne,
'prop_two': _propTwo
};
ClassToJsonTwo.fromJson(Map<String, dynamic> json):
_propOne = json['prop_one'],
_propTwo = json['prop_two'];
#override
String toString() => 'Second Class: $_propOne, $_propTwo';
}
main(List<String> args) {
print('------- Declare Objecr -------\n');
var objectToJsonOne = ClassToJsonOne('I am the fist object', 'empty');
var objectToJsonTwo = ClassToJsonTwo('I contains the first object', 'empty');
String jsonStringObjOne = jsonEncode(objectToJsonOne.toJSon());
print('\n---------- Object one JSON format ---------\n');
print(jsonStringObjOne);
String jsonStringObjTwo = jsonEncode(objectToJsonTwo.toJSon());
print('\n---------- Object one JSON format ---------\n');
print(jsonStringObjTwo);
print('\n---------- DECODE JSON to OBJECT ---------\n');
var fromJsonObjectOne = jsonDecode(jsonStringObjOne);
print(fromJsonObjectOne.toString());
var fromJsonObjectTwo = jsonDecode(jsonStringObjTwo);
print(fromJsonObjectTwo.toString());
}
Inside the classes, you can see the following methods
Map<String, dynamic> toJSon() => {
'prop_one': _propOne,
'prop_two': _propTwo
};
ClassToJsonTwo.fromJson(Map<String, dynamic> json):
_propOne = json['prop_one'],
_propTwo = json['prop_two'];
The result of the method toJSon, you should be pass to the method of the library jsonEncode and when you go to deserialize you can use the library method jsonDecode(youtStringJSOn) and the result you can pass to the method of your class fromJson.
In addition, you can configure the library json_serializable.
In conclusion, I want to fix my comment
I think the json_serializable worked how GSON, I can make an example for you, on this day.
On flutter, documentation has reported this text
Is there a GSON/Jackson/Moshi equivalent in Flutter?
The simple answer is no.
Such a library would require using runtime reflection, which is disabled in Flutter. Runtime reflection interferes with tree shaking, which Dart has supported for quite a long time. With tree shaking, you can “shake off” unused code from your release builds. This optimizes the app’s size significantly.
Since reflection makes all code implicitly used by default, it makes tree shaking difficult. The tools cannot know what parts are unused at runtime, so the redundant code is hard to strip away. App sizes cannot be easily optimized when using reflection.
Although you cannot use runtime reflection with Flutter, some libraries give you similarly easy-to-use APIs but are based on code generation instead. This approach is covered in more detail in the code generation libraries section.
you can found the source code inside this answer here
This question is about Dart language.
I want to have a class which is just a List but with some extra functionality.
For example I have a class named Model:
class Model{
String name;
int type;
Model(this.name, this.type);
}
I know that Model's type could take only four values: from 0 to 3.
And I want to have a method, which can give me a List of Models of specified type, e.g. List<Model> modelCollection.getByType(int type);.
I plan to to have four 'hidden' Lists of the Models (grouped by type) in that class.
Thus I need to override addition and removal of List elements to make that hidden lists being up to date.
How can I realize this as easy as possible?
P.S. I know this is quite simple, but I'm poorly familiar with Object inheritance and can't find proper examples.
P.P.S. I've also checked this but don't know is it outdated or not and didn't catch the idea.
To make a class implement List there are several ways :
Extending ListBase and implementing length, operator[], operator[]= and length= :
import 'dart:collection';
class MyCustomList<E> extends ListBase<E> {
final List<E> l = [];
MyCustomList();
void set length(int newLength) { l.length = newLength; }
int get length => l.length;
E operator [](int index) => l[index];
void operator []=(int index, E value) { l[index] = value; }
// your custom methods
}
Mixin ListMixin and implementing length, operator[], operator[]= and length= :
import 'dart:collection';
class MyCustomList<E> extends Base with ListMixin<E> {
final List<E> l = [];
MyCustomList();
void set length(int newLength) { l.length = newLength; }
int get length => l.length;
E operator [](int index) => l[index];
void operator []=(int index, E value) { l[index] = value; }
// your custom methods
}
Delegating to an other List with DelegatingList from the quiver package:
import 'package:quiver/collection.dart';
class MyCustomList<E> extends DelegatingList<E> {
final List<E> _l = [];
List<E> get delegate => _l;
// your custom methods
}
Depending on your code each of those options have their advantages. If you wrap/delegate an existing list you should use the last option. Otherwise use one of the two first options depending on your type hierarchy (mixin allowing to extend an other Object).
A basic approach is to extend an Object with IterableMixin. It also seems that you don't even need to override the "length" getter or let's say all methods that the IterableMixin already provides.
import 'dart:collection';
class Model {
String name;
int type;
Model(this.name, this.type) {
}
}
class ModelCollection extends Object with IterableMixin {
List<Model> _models;
Iterator get iterator => _models.iterator;
ModelCollection() {
this._models = new List<Model>();
}
//get one or the first type
Model elementByType(int type) {
for (Model model in _models) {
if (model.type == type) {
return model;
}
}
}
//get all of the same type
List<Model> elementsByType(int type) {
List<Model> newModel = new List<Model>();
for (Model model in _models) {
if (model.type == type) {
newModel.add(model);
}
}
return newModel;
}
add(Model model) {
this._models.add(model);
}
}
Excuse my strong static typing.
You might be interested in quiver.dart's Multimap. It behaves like a Map that allows multiple values per key.
Here's the code on github: https://github.com/google/quiver-dart/blob/master/lib/src/collection/multimap.dart#L20
It's on pub simply as quiver. We'll be hosting the dartdocs somewhere soon.