设置不删除重复日期
Set not Removing Duplicate Dates
我有一个显示按日期排序的条目的结构。对于同一日期的所有条目,日期只显示一次。我遇到的问题是 Set
没有删除重复的日期。如果我有两个具有相同日期的条目,我在视图中有两个块,每个块中都有相同的条目。请参阅我的原始 post 如果我输入具有相同日期的多个条目,uniqueDates(使用调试器查找)会显示具有相同日期的相同数量的元素。
我的理论是 Array(Set(wdvm.wdArray)) 在完整的未格式化日期上排序,其中包括每个元素中的时间或其他变量。因此它认为所有日期都是唯一的。有没有使用格式化日期进行排序的方法?
struct WithdrawalView: View {
@StateObject var wdvm = Withdrawal()
var uniqueDates: [String] {
Array(Set(wdvm.wdArray)) // This will remove duplicates, but WdModel needs to be Hashable
.sorted { [=10=].wdDate < .wdDate } // Compare dates
.compactMap {
[=10=].wdDate.formatted(date: .abbreviated, time: .omitted) // Return an array of formatted the dates
}
}
// filters entries for the given date
func bankEntries(for date: String) -> [WdModel] {
return wdvm.wdArray.filter { [=10=].wdDate.formatted(date: .abbreviated, time: .omitted) == date }
}
var body: some View {
GeometryReader { g in
VStack (alignment: .leading) {
WDTitleView(g: g)
List {
if wdvm.wdArray.isEmpty {
NoItemsView()
} else {
// outer ForEach with unique dates
ForEach(uniqueDates, id: \.self) { dateItem in // change this to sort by date
Section {
// inner ForEach with items of this date
ForEach(bankEntries(for: dateItem)) { item in
wdRow(g: g, item: item)
}
} header: {
Text("\(dateItem)")
}
}.onDelete(perform: deleteItem)
}
}
.navigationBarTitle("Bank Withdrawals", displayMode: .inline)
下面是本模块使用的class
struct WdModel: Codable, Identifiable, Hashable {
var id = UUID()
var wdDate: Date // bank withdrawal date
var wdCode: String // bank withdrawal currency country 3-digit code
var wdBank: String // bank withdrawal bank
var wdAmtL: Double // bank withdrawal amount in local currency
var wdAmtH: Double // bank withdrawal amount in home currency
var wdCity: String
var wdState: String
var wdCountry: String
}
class Withdrawal: ObservableObject {
@AppStorage(StorageKeys.wdTotal.rawValue) var withdrawalTotal: Double = 0.0
@Published var wdArray: [WdModel]
init() {
if let wdArray = UserDefaults.standard.data(forKey: StorageKeys.wdBank.rawValue) {
if let decoded = try? JSONDecoder().decode([WdModel].self, from: wdArray) {
self.wdArray = decoded
return
}
}
self.wdArray = []
// save new withdrawal data
func addNewWithdrawal(wdDate: Date, wdCode: String, wdBank: String, wdAmtL: Double, wdAmtH: Double, wdCity: String, wdState: String, wdCountry: String) -> () {
self.withdrawalTotal += wdAmtH
let item = WdModel(wdDate: wdDate, wdCode: wdCode, wdBank: wdBank, wdAmtL: wdAmtL, wdAmtH: wdAmtH, wdCity: wdCity, wdState: wdState, wdCountry: wdCountry)
wdArray.append(item)
if let encoded = try? JSONEncoder().encode(wdArray) { // save withdrawal entries
UserDefaults.standard.set(encoded, forKey: StorageKeys.wdBank.rawValue)
}
}
}
我试图在一个日期下显示同一日期的所有条目。这个例子显示了我想要的但不是日期和条目的 3 个副本。
要Set
删除重复的日期,请尝试这样的操作:
var uniqueDates: [String] {
Array(Set(wdvm.wdArray.map { [=10=].wdDate }))
.sorted { [=10=] < }
.compactMap {
[=10=].formatted(date: .abbreviated, time: .omitted)
}
}
编辑-3:
到display
给定日期的唯一bankEntries
,基于日期的日、月和年(不是秒等...):
struct ContentView: View {
@State var wdArray = [WdModel]()
let frmt: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "MMM dd, yyyy"
return formatter
}()
func bankEntries(for date: String) -> [WdModel] {
return wdArray.filter { frmt.string(from: [=11=].wdDate) == date }
}
var uniqueDates: [String] {
Array(Set(wdArray.map { frmt.string(from: [=11=].wdDate) }))
.sorted { frmt.date(from: [=11=]) ?? Date() < frmt.date(from: ) ?? Date() }
.compactMap { [=11=] }
}
var body: some View {
List {
// outer ForEach with unique dates
ForEach(uniqueDates, id: \.self) { dateItem in // change this to sort by date
Section {
// inner ForEach with items of this date
ForEach(bankEntries(for: dateItem)) { item in
// wdRow(g: g, item: item)
HStack {
Text(item.wdDate.formatted(date: .abbreviated, time: .omitted))
Text(item.wdCode).foregroundColor(.red)
}
}
} header: {
Text("\(dateItem)")
}
}
}
.onAppear {
let today = Date() // <-- here
let otherDate = Date(timeIntervalSince1970: 345678)
wdArray = [
WdModel(wdDate: today, wdCode: "EUR", wdBank: "Bank of Innsbruck", wdAmtL: 4575, wdAmtH: 1625, wdCity: "Innsbruck", wdState: " Tyrol", wdCountry: "Aus"),
WdModel(wdDate: otherDate, wdCode: "CHF", wdBank: "Bank of Interlaken", wdAmtL: 6590, wdAmtH: 2305, wdCity: "Interlaken", wdState: "Bernese Oberland ", wdCountry: "CHF"),
WdModel(wdDate: today, wdCode: "USD", wdBank: "Bank X", wdAmtL: 1200, wdAmtH: 3275, wdCity: "Las Vegas", wdState: "NV", wdCountry: "USA")
]
}
}
}
我有一个显示按日期排序的条目的结构。对于同一日期的所有条目,日期只显示一次。我遇到的问题是 Set
没有删除重复的日期。如果我有两个具有相同日期的条目,我在视图中有两个块,每个块中都有相同的条目。请参阅我的原始 post
我的理论是 Array(Set(wdvm.wdArray)) 在完整的未格式化日期上排序,其中包括每个元素中的时间或其他变量。因此它认为所有日期都是唯一的。有没有使用格式化日期进行排序的方法?
struct WithdrawalView: View {
@StateObject var wdvm = Withdrawal()
var uniqueDates: [String] {
Array(Set(wdvm.wdArray)) // This will remove duplicates, but WdModel needs to be Hashable
.sorted { [=10=].wdDate < .wdDate } // Compare dates
.compactMap {
[=10=].wdDate.formatted(date: .abbreviated, time: .omitted) // Return an array of formatted the dates
}
}
// filters entries for the given date
func bankEntries(for date: String) -> [WdModel] {
return wdvm.wdArray.filter { [=10=].wdDate.formatted(date: .abbreviated, time: .omitted) == date }
}
var body: some View {
GeometryReader { g in
VStack (alignment: .leading) {
WDTitleView(g: g)
List {
if wdvm.wdArray.isEmpty {
NoItemsView()
} else {
// outer ForEach with unique dates
ForEach(uniqueDates, id: \.self) { dateItem in // change this to sort by date
Section {
// inner ForEach with items of this date
ForEach(bankEntries(for: dateItem)) { item in
wdRow(g: g, item: item)
}
} header: {
Text("\(dateItem)")
}
}.onDelete(perform: deleteItem)
}
}
.navigationBarTitle("Bank Withdrawals", displayMode: .inline)
下面是本模块使用的class
struct WdModel: Codable, Identifiable, Hashable {
var id = UUID()
var wdDate: Date // bank withdrawal date
var wdCode: String // bank withdrawal currency country 3-digit code
var wdBank: String // bank withdrawal bank
var wdAmtL: Double // bank withdrawal amount in local currency
var wdAmtH: Double // bank withdrawal amount in home currency
var wdCity: String
var wdState: String
var wdCountry: String
}
class Withdrawal: ObservableObject {
@AppStorage(StorageKeys.wdTotal.rawValue) var withdrawalTotal: Double = 0.0
@Published var wdArray: [WdModel]
init() {
if let wdArray = UserDefaults.standard.data(forKey: StorageKeys.wdBank.rawValue) {
if let decoded = try? JSONDecoder().decode([WdModel].self, from: wdArray) {
self.wdArray = decoded
return
}
}
self.wdArray = []
// save new withdrawal data
func addNewWithdrawal(wdDate: Date, wdCode: String, wdBank: String, wdAmtL: Double, wdAmtH: Double, wdCity: String, wdState: String, wdCountry: String) -> () {
self.withdrawalTotal += wdAmtH
let item = WdModel(wdDate: wdDate, wdCode: wdCode, wdBank: wdBank, wdAmtL: wdAmtL, wdAmtH: wdAmtH, wdCity: wdCity, wdState: wdState, wdCountry: wdCountry)
wdArray.append(item)
if let encoded = try? JSONEncoder().encode(wdArray) { // save withdrawal entries
UserDefaults.standard.set(encoded, forKey: StorageKeys.wdBank.rawValue)
}
}
}
要Set
删除重复的日期,请尝试这样的操作:
var uniqueDates: [String] {
Array(Set(wdvm.wdArray.map { [=10=].wdDate }))
.sorted { [=10=] < }
.compactMap {
[=10=].formatted(date: .abbreviated, time: .omitted)
}
}
编辑-3:
到display
给定日期的唯一bankEntries
,基于日期的日、月和年(不是秒等...):
struct ContentView: View {
@State var wdArray = [WdModel]()
let frmt: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "MMM dd, yyyy"
return formatter
}()
func bankEntries(for date: String) -> [WdModel] {
return wdArray.filter { frmt.string(from: [=11=].wdDate) == date }
}
var uniqueDates: [String] {
Array(Set(wdArray.map { frmt.string(from: [=11=].wdDate) }))
.sorted { frmt.date(from: [=11=]) ?? Date() < frmt.date(from: ) ?? Date() }
.compactMap { [=11=] }
}
var body: some View {
List {
// outer ForEach with unique dates
ForEach(uniqueDates, id: \.self) { dateItem in // change this to sort by date
Section {
// inner ForEach with items of this date
ForEach(bankEntries(for: dateItem)) { item in
// wdRow(g: g, item: item)
HStack {
Text(item.wdDate.formatted(date: .abbreviated, time: .omitted))
Text(item.wdCode).foregroundColor(.red)
}
}
} header: {
Text("\(dateItem)")
}
}
}
.onAppear {
let today = Date() // <-- here
let otherDate = Date(timeIntervalSince1970: 345678)
wdArray = [
WdModel(wdDate: today, wdCode: "EUR", wdBank: "Bank of Innsbruck", wdAmtL: 4575, wdAmtH: 1625, wdCity: "Innsbruck", wdState: " Tyrol", wdCountry: "Aus"),
WdModel(wdDate: otherDate, wdCode: "CHF", wdBank: "Bank of Interlaken", wdAmtL: 6590, wdAmtH: 2305, wdCity: "Interlaken", wdState: "Bernese Oberland ", wdCountry: "CHF"),
WdModel(wdDate: today, wdCode: "USD", wdBank: "Bank X", wdAmtL: 1200, wdAmtH: 3275, wdCity: "Las Vegas", wdState: "NV", wdCountry: "USA")
]
}
}
}