我有一个保持交易的案例类(假设为资金转移)。为简单起见,我将在下面使用
case class Trans(from: String, to: String, amount: Int)
我有交易清单
val tl = List(
Trans("a", "b", 30),
Trans("a", "c", 40),
Trans("b", "c", 10),
Trans("b", "a", 25),
Trans("c", "a", 15)
)
我想根据从和到对此列表进行分组。然后需要将组的总和加到 Map 。地图将元素保存在以下结构中
("a" -> (70, 40))
// "a" is the key
// "70" is the sum of values where "a" is 'from' (30 + 40)
// "40" is the sum of values where "a" is 'to' (25 + 15)
对于实例,about列表应将输出填充为
Map("a" -> (70, 40), "b" -> (35, 30), "c" -> (15, 50))
我可以使用两个语句进行过滤,并将它们组合起来,如下所示
// out map
val mOut = tl.map(t => (t.from, t.amount)).groupBy(_._1).map(s => (s._1, s._2.sum))
// in map
val mIn = tl.map(t => (t.to, t.amount)).groupBy(_._1).map(s => (s._1, s._2.sum))
// finally I can join these tow maps to have the final output
有没有办法用单/一个声明来做?
答案 0 :(得分:2)
如果您是cats
或scalaz
用户,则可以使用foldMap
:
import cats._, implicits._ // or...
//import scalaz._, Scalaz._
case class Trans(from: String, to: String, amount: Int)
val tl = List(
Trans("a", "b", 30),
Trans("a", "c", 40),
Trans("b", "c", 10),
Trans("b", "a", 25),
Trans("c", "a", 15)
)
tl foldMap {
case Trans(from, to, am) => Map(from -> (am, 0), to -> (0, am))
}
答案 1 :(得分:2)
你不需要scalaz。 。
我想,你要找的是import tkinter as tk
import sys
from tkinter import messagebox
name=("user")
password=("python3")
def login_in():
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
entry1.set("") # This clears entry1
entry2.set("") # this clears entry2
def close():
log.destroy() #Removes toplevel window
root.destroy() #Removes root window
sys.exit() #Ends the script
def session_end():
messagebox.showinfo("session expired","kindly login again")
def continue_session():
root.deiconify()
root=tk.Tk()
log = tk.Toplevel() #
root.geometry("350x350")
log.geometry("200x200")
entry1 = tk.Entry(log) #Username entry
entry2 = tk.Entry(log) #Password entry
check = tk.Checkbutton(log,text="keep me
login",command=continue_session)#root should stay when you tick checkbutton
button1 = tk.Button(log, text="Login", command=login_in) #Login button
button2 = tk.Button(log, text="Cancel", command=close) #Cancel button
label1 = tk.Label(root, text="This main ui after being idle for 5 minutes \n
You need to login for the main ui to open")
entry1.pack()
entry2.pack()
check.pack()
button1.pack()
button2.pack()
label1.pack()
root.withdraw()
root.after(5000,session_end())
root.mainloop()
:
import tkinter as tk
import sys
name=("user")
password=("python3")
after_id=None
def reset_timer(event=None):
global after_id
if after_id is not None:
root.after_cancel(after_id)
after_id = root.after(300000,session_end)
def login_in():
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def close():
log.destroy() #Removes toplevel window
root.destroy() #Removes root window
sys.exit() #Ends the script
def session_end():
messagebox.showinfo("session expired","kindly login again")
def continue_session():
if after_id is not None:
root.deiconify()
def print_some():
print("This is idle timeout")
root=tk.Tk()
log = tk.Toplevel() #
root.geometry("350x350")
log.geometry("200x200")
entry1 = tk.Entry(log) #Username entry
entry2 = tk.Entry(log) #Password entry
check = tk.Checkbutton(log,text="keep me
login",command=continue_session)#root should stay when you tick checkbutton
button1 = tk.Button(log, text="Login", command=login_in) #Login button
button2 = tk.Button(log, text="Cancel", command=close) #Cancel button
label1 = tk.Label(root, text="This main ui after being idle for 5 minutes \n
You need to login for the main ui\to open")
print_button = tk.Button(root,text="print",command=print_some).pack()
entry1.pack()
entry2.pack()
check.pack()
button1.pack()
button2.pack()
label1.pack()
root.withdraw()
root.bind_all("<Any-KeyPress>",reset_timer)
root.bind_all("<Any-ButtonPress>",reset_timer)
root.mainloop()
答案 2 :(得分:1)
这似乎只能在列表中进行一次遍历。
tl.foldLeft(Map.empty[String,(Int,Int)].withDefaultValue((0,0))){
case (m,Trans(from,to,amount)) =>
val (fromA, fromB) = m(from)
val (toA, toB) = m(to)
m + (from -> (fromA+amount, fromB)) + (to -> (toA, toB+amount))
}
//res0: Map[String,(Int, Int)] = Map(a -> (70,40), b -> (35,30), c -> (15,50))
希望你能为中间变量找到更好的名字。