你好,我正在做一个项目,我有一个多维数组,名字和投票,这是数组
[[[Avoos, 0]], [[Abhiram MS, 1]], [[Amritha tg, 0]], [[usha, 2]]]
我从服务器获得了这个值,问题是每次刷新页面时,它都会将这些值再次存储在数组中(重复相同的值),因此它会得到如下所示的值
[[[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]]]
我想删除这些重复的值并根据投票对数组排序
这里是我的完整的代码使用的网页
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]}'),
);
}),
),
],
),
),
),
);
}
}
2条答案
按热度按时间7vux5j2d1#
这看起来很像是一个模型类会让100倍简单的任务,而不是使用一个多维数组,你可能会犯各种不同的错误,你可以把数据组合成一个单独的对象,并获得IDE的支持。
在您的示例中,该类可能如下所示:
当您在
FutureBuilder
中接收到数据时,您需要将列表的列表转换为这些对象的列表。这已经好得多了,但还有更多!你可以实现
=
=和hashCode
重写,这允许你比较两个相同的对象,并确定它们是否相等。现在你可以在任何地方比较它们,只要写
==
:这也允许你不用存储返回的列表
candidatesnapshot.data
,你可以创建一个Set
,它只允许任何给定的值在其中存储一次!如果你不想添加重复的值,这会自动地消除你添加重复的值。要做到这一点,你必须修改
FutureBuilder
之后的代码。我不想撒谎,我真的不明白那里发生了什么,因为你似乎要为Stream
返回的每个对象创建一个新的FutureBuilder
。无论哪种方式,我认为最好是简单地循环流中的值,并将数据添加到Set
。现在,您还可以轻松地对
MyObjects
的集合进行排序,只需将值作为列表获取,然后使用listsx 1 m11n1x方法。由于类型只有
int
和string
,所以可以使用它们的compareTo
方法自动排序,要颠倒顺序,只需在排序函数上颠倒a
和b
即可!如果你因为某种原因不能使用一个模型类--我 * 真的 * 不明白你为什么不能--仍然可以通过以下方法过滤掉重复的:
x = ..
代替x.add()
.contains()
方法来检查重复项至于排序,您可以使用
.sort()
方法,您只需要使用[index]
语法,而不是右侧的对象字段,这确实也不是很好。yyyllmsg2#
要删除重复值并根据投票对数组进行排序,可以使用
toSet()
函数,然后使用toList()
将其转换回列表。这将删除任何重复值。然后可以使用sort()
函数根据投票对数组进行排序。首先将
candidatearrayreal
转换为一个集合,这将删除所有重复的值,然后将其转换回列表,接下来,它将使用sort()
函数和一个比较器函数(比较两个候选者的投票)根据每个子列表的第二个元素(即投票数)对列表进行排序。您可以将这段代码放在
refresh()
函数中,这样它就会在用户每次刷新页面时执行。此外,您可以将
candidatearray.clear();
代码移动到initState()
函数,这将在用户每次进入CloseElec页面时清除阵列。