I'm having trouble accessing an array value in Flutter - arrays

In my code I have a dropdown that receives the values ​​from a list but these values ​​are within the variable value of the dropdown and I can't access the first or second value. Follow the code:
List<int> cilindro1 = [4145, 2100];
List<int> cilindro2 = [4405, 2085];
List<int> cilindro3 = [4140, 2095];
child: DropdownButton<String>(
items: [
DropdownMenuItem<String>(
child: Text('Cilindro 1'),
value: '$cilindro1',
),
DropdownMenuItem<String>(
child: Text('Cilindro 2'),
value: '${cilindro2}',
),
DropdownMenuItem<String>(
child: Text('Cilindro 3'),
value: '${cilindro3}',
),
],
onChanged: (String value) {
setState(() {
_valoresArray = value;
});
},
The variable that contains the values ​​is _valoresArray and I can't choose the index from it.

I have solved the problem using substring.
var peso = value.substring(1, 5);
var volume = value.substring(7, 11);
_peso = peso;
_volume = volume;

Related

Sorting and removing duplicates of multi dimensional array flutter

Hello I am working on a project here I have a multidimensional array with name and votes this is the array
[[[Avoos, 0]], [[Abhiram MS, 1]], [[Amritha tg, 0]], [[usha, 2]]]
I get this from the server,the problem is every time I refresh the page it stores these values again in the array(repeating the same values) so its getting something like this
[[[Avoos, 0]], [[Abhiram MS, 1]], [[Amritha tg, 0]], [[usha, 2]], [[Amritha tg, 0]], [[Abhiram MS, 1]], [[Avoos, 0]], [[usha, 2]], [[Amritha tg, 0]], [[Abhiram MS, 1]], [[Avoos, 0]], [[usha, 2]]]
I want to remove these repeated values and sort this array according to the votes
here is my complete code used on the page
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:web3dart/web3dart.dart';
import '../../services/Auth.dart';
import '../../services/IntoLogin.dart';
import '../../services/functions.dart';
class CloseElec extends StatefulWidget {
final Web3Client ethClient;
final String electionName;
final String electionAdress;
const CloseElec({Key? key, required this.ethClient, required this.electionName, required this.electionAdress}) : super(key: key);
#override
State<CloseElec> createState() => _CloseElecState();
}
class _CloseElecState extends State<CloseElec> {
void refresh() {
setState(() {
//candidatearray.clear();
candidatearray =candidatearrayreal.toSet().toList();
});
}
Future<void> signOut() async {
if (!mounted) return;
await Auth().signOut();
if (!mounted) return;
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => IntroLogin()),
(route) => false);
}
late String winner = 'No candidate';
late int winnervotes = 0;
late int row = 5;
late int col = 5;
var candidatearray = [] ;
var candidatearrayreal = [] ;
#override
void initState() {
candidatearray.clear();
super.initState();
}
#override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(gradient:
LinearGradient(colors: [
Color(0xFF516395),
Color(0xFF614385 ),
])),
child: Scaffold(
appBar:AppBar(
backgroundColor: Colors.transparent,
leading: IconButton(onPressed: () {
signOut();
}, icon: const Icon(Icons.logout_sharp),),
title: const Text('Election progress'),
actions: [
IconButton(onPressed: () {
refresh();
}, icon: const Icon(Icons.refresh))
],
),
body: SingleChildScrollView( //Here we are getting the whole candidate details
child: Column(
children: [
Container(margin: const EdgeInsets.only(bottom: 56),
child: SingleChildScrollView( // this stream builder will give the number of items/candidates
child: StreamBuilder<List>(stream: getCandidatesNum(widget.ethClient, widget.electionAdress).asStream(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator(),);//circular bar for waiting
} else {
return Column(
children: [ // here we will get all candidates using a loop
for (int i = 0; i < snapshot.data![0].toInt(); i++)
FutureBuilder<List>( // call to get candidate info
future: candidateInfo(i, widget.ethClient, widget.electionAdress),
builder: (context, candidatesnapshot) {
if (candidatesnapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator(),);
} else {
// logic to decide the winner
if(candidatesnapshot.data![0][1].toInt() > winnervotes){
winnervotes = candidatesnapshot.data![0][1].toInt();
winner = candidatesnapshot.data![0][0];
}else if(candidatesnapshot.data![0][1].toInt() == winnervotes){
winner = candidatesnapshot.data![0][0];
}
candidatearrayreal.add(candidatesnapshot.data);
// print(candidatesnapshot.data);
return Container(
padding: const EdgeInsets.all(12),
margin: const EdgeInsets.all(12),
decoration: const BoxDecoration(
boxShadow: [
BoxShadow(color: Color(0xFF7F5A83),
offset: Offset(-11.9, -11.9),
blurRadius: 39,
spreadRadius: 0.0,
),
BoxShadow(color: Color(0xFF7F5A83),
offset: Offset(11.9, 11.9),
blurRadius: 39,
spreadRadius: 0.0,
),
],
borderRadius: BorderRadius.all(Radius.circular(10)),
gradient: LinearGradient(colors: [
Color(0xFF74F2CE),
Color(0xFF7CFFCB),
])),
child: ListTile(
title: Text('Name: ${candidatesnapshot.data![0][0]}',
style: const TextStyle(color: Colors.purple)),
subtitle: Text('Votes: ${candidatesnapshot.data![0][1]}',
style: const TextStyle(color: Colors.purple)),
),
);
}
})
],
);
}
},
),
),
),
const SizedBox(height: 12,),
Text('The winner of the election is : $winner with votes $winnervotes',style: const TextStyle(color: Colors.white)),
const SizedBox(height: 16,),
SizedBox(
height: MediaQuery.of(context).size.height,
width: double.infinity,
child: ListView.builder(
itemCount:candidatearray.length,
itemBuilder: (context,index){
for (var i = 0; i < candidatearray.length; i++) {
candidatearray.sort((a, b) {
print(candidatearrayreal);
//print(b[0][1]);
return int.parse(a[0][1].toString()).compareTo(int.parse(b[0][1].toString()));
});
}
return ListTile(
title: Text('${candidatearray[index][0][0]}'),
subtitle:Text('votes : ${candidatearray[index][0][1]}'),
);
}),
),
],
),
),
),
);
}
}
This seems a lot like a task a model class would make 100 times easier. Instead of using a multi-dimensional array where you might make various different mistakes, you can combine the data into a single object and get IDE support too.
In your case, that class could look like this:
class MyObject {
final String name;
final int votes;
MyObject({required this.name, required this.votes});
}
When you receive the data in your FutureBuilder you will need to transform the list of lists into a list of these objects. This is already much better, but there's more!
You can implement the == and hashCode overrides which allows you to compare two of the same objects and determine whether they are equal or not. Write this in your model class too:
#override
bool operator ==(covariant MyObject other) {
if (identical(this, other)) return true;
return
other.name == name &&
other.votes == votes &;
}
#override
int get hashCode {
return name.hashCode ^
votes.hashCode;
}
Now you can compare them anywhere by simply writing ==:
MyObject a = MyObject(name: "test", votes: 10);
MyObject b = MyObject(name: "test", votes: 10);
MyObject c = MyObject(name: "xyz", votes: 0);
print(a == b); // true
print(a == c); // false
What this also allows you to do is instead of storing the returned list candidatesnapshot.data, you can create a Set, which only allows any given value to be stored inside it a single time! This automatically eliminates you from adding duplicates, if that isn't what you want.
To do this, you're going to have to fix up the code after your FutureBuilder. I'm not going to lie, I don't really understand what's going on there since you seem to be creating a new FutureBuilder for every object returned by the Stream. Either way, I think it would be best to simply loop over the values from the stream and add the data to the Set.
Now, you can also easily sort this set of your MyObjects. Simply get the values as a list and then use the lists .sort method.
Set<MyObjects> m = {...}; // your data goes here
final sortedList = m.toList()..sort((a, b) => a.votes.compareTo(b.votes));
Since the types are only int and string, you can use their compareTo methods and automatically sort them. To reverse the order, simply reverse a and b on the sort function!
If you for some reason can't use a model class - and I really don't see why you couldn't - it is still possible to filter out duplicates by either:
overwriting the list every time you get new data (using x = .. instead of x.add()
checking for duplicates by looping over the list for every new value / using the .contains() method on the list
As for sorting, you can use the .sort() method, you'll just have to use a [index] syntax instead of object fields on the right side, which really isn't great either.
To remove the repeated values and sort the array according to the votes, you can use the toSet() function and then convert it back to a list using toList(). This will remove any duplicate values. Then you can use the sort() function to sort the array according to the votes.
candidatearray = candidatearrayreal.toSet().toList();
candidatearray.sort((a, b) => a[1].compareTo(b[1]));
This will first convert the candidatearrayreal to a set, which will remove any duplicate values, and then convert it back to a list. Next, it will sort the list according to the second element of each sublist (which is the number of votes) using the sort() function and a comparator function that compares the votes of the two candidates.
You can put this piece of code in the refresh() function, so it will be executed every time the user refreshes the page.
Also, you can move the candidatearray.clear(); code to the initState() function, this will clear the array every time the user enters the CloseElec page.

How to compare 2 arrays of different lengths and look for matching values - Flutter

I'm not sure if my strategy or logic is correct to achieve this, but I have 2 lists coming from 2 different jsondata mysql queries, let's say they look like this:
List newsAgency = [{id: 1, name: 9news, image: x}
{id: 2, name: abcnews, image: y}
{id: 3, name: bbcnews, image:z}];
List following = [{userid: 41, username: x, newsid: 2}
{userid: 41, username: x newsid: 3}];
I want to see if the id in newsAgency matches the newsid in the following list, and to return true or false correspondingly.
The idea is to say that I am following 2 news agencies out of 3, so my goal is to display the button to follow or unfollow based on the results.
I tried everything suggested from this post how can I find a list contains in any element another list in flutter? but couldn't get it.
This is my code example:
Listview.builder(
itemCount: newsAgency.length,
itemBuilder: (BuildContext context, int index) {
bool following = false;
return Card(
elevation: 10.0,
child: Row(
children: [
Text(newsAgency[index]['name'],
following
? TextButton(onPressed: () {//unfollow function},
child: const Text('unfollow')),
: TextButton(onPressed: () {//follow function},
child: const Text('follow')),
]));});
Any help is highly appreciated
add this method in your class, it will be responsible for searching which items are following and which are not, and return a bool based on it:
bool checkIsFollowing(Map<String, dynamic> current) {
for(int index = 0; index < following.length; index+=1) {
if(current["id"] == following[index]["newsid"]) {
return true;
}
}
return false;
}
now inside of your ListView's itemBuilder, replace this:
bool following = false;
with this:
final currentNewsAgency = newsAgency[index];
bool following = checkIsFollowing(currentNewsAgency);
following will be true or false based on if the current Agency's id exists in some item in the following list.
use contains() method to check if the list contains the value you want to match or not, for example:-
following.contains(newsAgency[index]['name'].toString())// true if value matches.

sort an array of objects on multiple key using array-sort

I have a requirement where the array of objects needs to be sorted on certain keys. The keys with which it needs to be sorted is dynamic and it is Not fixed.
I came across array-sort in npm library. Using that, am able to sort on multiple keys but it sorts only on ascending order.
const input = [{id:'1',name:'John',city:'Denver',State:'CO'},
{id:'2',name:'Smith',city:'San Fransisco',State:'CA'},
{id:'3',name:'Adam',city:'Concord',State:'CA'},
{id:'1',name:'John',city:'Concord',State:'CA'}]
I want to sort on State (asc), city (asc) and id (desc). My output should look like
[
{id:'3',name:'Adam',city:'Concord',State:'CA'},
{id:'1',name:'John',city:'Concord',State:'CA'},
{id:'2',name:'Smith',city:'San Fransisco',State:'CA'},
{id:'1',name:'John',city:'Denver',State:'CO'}]
Can anyone please let me know how i can implement sorting on descending using array-sort
Thanks
Maybe you want a JavaScript function like this?
function multicolumnSort(data, orders) {
return data.sort((e1, e2) => {
for (var i = 0; i < orders.length; i++)
if (e1[orders[i].column] != e2[orders[i].column])
return orders[i].desc ^ e2[orders[i].column] < e1[orders[i].column]? 1 : -1;
return 0;
});
}
Then, you may call the function with your order keys:
let orders = [
{
column: 'State'
},
{
column: 'city'
},
{
column: 'id',
desc: true
}
];
let result = multicolumnSort(input, orders);
Check my code
function DESC(i, ii) { // DESC
return (i[key] > ii[key]) ? -1 : ((i[key] < ii[key]) ? 1 : 0);
}
function ASC(i, ii) { // ASC
return (i[key] > ii[key]) ? 1 : ((i[key] < ii[key]) ? -1 : 0);
}
function StartSort(data, myArray, order) {
// data - row for sorting, array - array fo sorting, order - order of sorting
key = data;
arr = myArray;
if (order.toUpperCase() == "ASC") {
sortedArray = arr.sort(ASC);
} else {
sortedArray = arr.sort(DESC);
}
return sortedArray;
}
//sorting started
const input = [{
id: '1',
name: 'John',
city: 'Denver',
State: 'CO'
},
{
id: '2',
name: 'Smith',
city: 'San Fransisco',
State: 'CA'
},
{
id: '3',
name: 'Adam',
city: 'Concord',
State: 'CA'
},
{
id: '1',
name: 'John',
city: 'Concord',
State: 'CA'
}
]
let output1 = StartSort('state', input, 'ASC');
output1 = StartSort('city', output1, 'ASC');
output1 = StartSort('id', output1, 'DESC');
console.log(output1);

how to find the max value and the previous max value in array

I have an array of objects. I want to find the max value and the one before that.
arr : [{key:1, value: 1},{key:2, value: 2}, {key:3, value: 3}, {key:4, value: 4}, {key:5, value: 5}]
let largest = 0;
greater = 0;
val = [];
this.arr.forEach(aa => {
if (largest < Number(aa.value)) {
largest = Number(aa.value);
greater = aa.key;
}
});
}
The value of greater is 5; I want to get the value 4 too and push both of them to val array.
The best way to achieve the same is by using the Array prototype function sort().
What you need to do is sort in descending order and grab the first two elements.
MDN link for sort() documentation
Here's how I would write it.
let newArr = arr.sort(function(a, b){
return b.value-a.value;
});
Now you can grab the top two values in newArr.
Separate values of the array. Get the maximum value using Math.max, then filter your array and get another one which does not contain the max1 value from the first search and do the same on the filtered array.
const arr = [
{ key: 1, value: 1 },
{ key: 2, value: 2 },
{ key: 3, value: 3 },
{ key: 4, value: 4 },
{ key: 5, value: 5 }
];
const valuesMax1 = arr.map(item => item.value);
const max1 = Math.max(...valuesMax1);
const valuesMax2 = valuesMax1.filter(item => item !== max1);
const max2 = Math.max(...valuesMax2);
console.log(max1);
console.log(max2);
Another simple way is to sort array and get first two items
const arr = [
{ key: 1, value: 1 },
{ key: 2, value: 2 },
{ key: 3, value: 3 },
{ key: 4, value: 4 },
{ key: 5, value: 5 }
];
const sorted = arr.sort((f,s) => s.value - f.value);
console.log(sorted[0].value);
console.log(sorted[1].value);

Right way to partially update all items in an array with items from another array in redux reducer?

In Redux, what's the best practice to update all items in an array with items from another array only with the fields that are common to the 2 arrays.
So for example :
billArrayInStore = [{id, amount, dueDate, summary}, ...]
newBillArray = [{id, amount, dueDate}, ...]
Update each bill (amount, dueDate) but keep the 'summary' field untouched.
Thank you :)
You can use Array.prototype.map
newBillArray = billArrayInStore.map(bill => ({
...bill,
amount: 0, // new amount
dueDate: '', // new dueDate
}))
For each bill object in billArrayInStore, you want to see if there is a corresponding bill object in newBillArray by comparing IDs. If you find a matching bill object, you then merge the two bills together into a new object. These new bill objects are stored in a new array to avoid mutating the original.
Since this solution involves transforming existing bill objects and storing them in a new array, it's a perfect use case for Array.prototype.map.
const updatedBills = billArrayInStore.map(bill => {
// For each existing bill, check to see if there is a corresponding
// new bill by comparing bill IDs.
const newBill = newBillArray.find(newBill => newBill.id === bill.id);
// If there is a new bill, merge the bills together using spread syntax.
if (newBill) {
// Order matters here, you want to spread the new bill last so it
// can override any properties in the current bill. If the current
// bill has properties that don't exist in the new bill, they won't
// be changed.
return { ...bill, ...newBill };
}
// If there isn't a corresponding new bill, the current bill should be
// returned unmodified.
return bill;
});
Here's a snippet with a working example.
const billArrayInStore = [
{ id: 1, amount: 1000, summary: 'Rent' },
{ id: 2, amount: 50, summary: 'Internet' },
{ id: 3, amount: 110, summary: 'Electric' }
];
const newBillArray = [
{ id: 2, amount: 40 },
{ id: 3, amount: 125 }
];
const updatedBills = billArrayInStore.map(bill => {
const newBill = newBillArray.find(newBill => newBill.id === bill.id);
if (newBill) {
return { ...bill, ...newBill };
}
return bill;
});
console.log(updatedBills);

Resources