【问题标题】:check if one array contains all values of another array (do all the users have jobs assigned?)检查一个数组是否包含另一个数组的所有值(是否所有用户都分配了作业?)
【发布时间】:2017-10-11 00:26:10
【问题描述】:

完全是菜鸟问题,但我已经尽力了,无法弄清楚如何迭代我的数组并确定它是否包含另一个数组的所有值。

这是我的数组类(dailyJobs):

class JobsAndHabits {

var name: String
var multiplier: Double
var assigned: String
var order: Int

init(jobName: String, jobMultiplier: Double, jobAssign: String, jobOrder: Int) {

    self.name = jobName
    self.multiplier = jobMultiplier
    self.assigned = jobAssign
    self.order = jobOrder
}

这是我要检查的课程(用户):

class UserClass {

var imageURL: String
var firstName: String
var birthday: Int
var passcode: Int
var gender: String
var childParent: String

init(userProfileImageURL: String, userFirstName: String, userBirthday: Int, userPasscode: Int, userGender: String, isUserChildOrParent: String) {

    self.imageURL = userProfileImageURL
    self.firstName = userFirstName
    self.birthday = userBirthday
    self.passcode = userPasscode
    self.gender = userGender
    self.childParent = isUserChildOrParent

}

如果有帮助,这是我的 JSON 树:

{
"-Kw2SkmAqo3G_cVFP26Y" : {
"assigned" : "Aiden",
"multiplier" : 1,
"name" : "table",
"order" : 2
},
"-Kw2SkmAqo3G_cVFP26Z" : {
"assigned" : "Mom",
"multiplier" : 1,
"name" : "dishes",
"order" : 3
},
"-Kw2SyhJNkjKNQ-sKBeT" : {
"assigned" : "Sophie",
"multiplier" : 1,
"name" : "floors",
"order" : 0
},
"-Kw2SyhJNkjKNQ-sKBeU" : {
"assigned" : "Savannah",
"multiplier" : 1,
"name" : "laundry",
"order" : 1
},
"-Kw7H3pY2L5PzLLdd6qD" : {
"assigned" : "Dad",
"multiplier" : 1,
"name" : "another daily test",
"order" : 4
},
"-Kw7HAWwAvv5ZjYuNOrg" : {
"assigned" : "Sophie",
"multiplier" : 1,
"name" : "daily job testsaroo!",
"order" : 5 }

这是我尝试过的:

尝试 #1:

var tempArray = [String]()
    for user in self.users {
        for job in self.dailyJobs {
            if job.assigned == user.firstName {
                print(user.firstName,"has a job",job.name)
                tempArray.append(user.firstName)
            }
        }
    }
    for user in self.users {
        if tempArray.contains(user.firstName) {
            print("true")
        } else {
            print("false")
        }
    }

尝试 #2:(这甚至没有编译)

for job in self.dailyJobs {
        if self.users.contains(where: job) {
            print(true)
        }
    }

尝试 #3: 重复打印“失败”。

for job in self.dailyJobs {
        for user in self.users {
            if job.assigned != user.firstName {
                print("FAILED")
            }
        }
    }

如何检查我的用户数组中的每个用户是否至少分配了一项工作?换句话说,我如何确保在dailyJobs 数组中每个user.firstName 至少被表示一次?

我想我必须做一些循环,但我不确定如何继续。有人可以指出我正确的方向吗?现在我只是在兜圈子(如果你能原谅双关语的话)。

【问题讨论】:

  • 请注意,您应该只在极少数情况下使用class,使用引用而不是值是有意义的。对于大多数数据对象,您应该使用struct。然后你可以完全摆脱那些init 方法,因为structs 合成了一个设置所有属性的init。此外,在 Swift 4 中,如果您遵守 Codable 协议,您会自动从 JSON(可能还有其他数据结构)获取编码和解码。
  • 很好的信息。我是否能够以 1:1 的比例将我的类换成结构,还是需要完全重写我的代码?我的意思是,我可以进去把我的类改成一个结构体,一切都会好起来的,还是因为类和结构体不是可比较的对象而需要做更多的工作?
  • 除非您使用一些高度特定于类的语言功能,否则交换两者应该没什么问题。
  • 一些关于为什么使用一个而不是另一个的进一步阅读:stackoverflow.com/questions/24232799/…developer.apple.com/library/content/documentation/Swift/…
  • 我刚开始时阅读了苹果文档,它使class 看起来是更好的选择。所以现在我很困惑,因为你发给我的链接让我觉得structs 是要走的路。看来我还得做更多的研究。

标签: arrays swift loops


【解决方案1】:

尝试 #1 已接近。检查所有用户后,您只能说是true

func areAllAssigned(users: [UserClass], tempArray: [String]) -> Bool {
  for user in users {
    if !tempArray.contains(user.firstName) {
        return false
    }
  }
  return true
}

其实你不需要外层的for循环:

for job in self.dailyJobs {
    print(job.assigned, "has a job", job.name)
    tempArray.append(job.assigned)
}

areAllAssigned(users: self.users, tempArray: tempArray)

【讨论】:

  • 当您回答时,我自己想通了。感谢您的帮助。我会将您的答案标记为正确,因为这正是我最终所做的。
  • 太棒了!感谢您的标记:) 请注意,正如我的回答中提到的,您不需要嵌套的 for 循环来创建 tempArray
【解决方案2】:

以下是使用集合的方法(不使类可散列)。

if Set(users.map{firstName}).isSubset(of:dailyJobs.map{$0.assigned})
{
  // all users are assigned to at least one job
}
else
{
  let employed = Set(dailyJobs.map{$0.assigned})
  let jobless  = users.filter{ !employed.contains($0.firstName) }
}

【讨论】:

  • 如果你使用“过滤器”,则无需使用 Set。
  • 取决于作业和用户的数量,一个简单的过滤器将提供 O(n/2) 而集合将提供 O(1) + 设置时间。无论如何,我在这里的目的是展示一些集合相关功能的示例(不是为应对失业用户提供最佳解决方案)
【解决方案3】:

使类符合Hashable 并使用Set。你不需要那么多代码。

更新

您无需在此处使用Hashable。我误解了你的问题。我简化了代码,但基本上它有你需要的。

struct JobsAndHabits {
    let assigned: String
}

struct UserClass {
    let firstName: String
}

let users = [UserClass(firstName: "person_a"),
             UserClass(firstName: "person_b"),
             UserClass(firstName: "person_c"),
             UserClass(firstName: "person_d")]

let jobs = [JobsAndHabits(assigned: "person_a"),
            JobsAndHabits(assigned: "person_c")]

let names = Set(users.map({ return $0.firstName }))
let assigned = Set(jobs.map({ return $0.assigned }))

print(names.subtracting(assigned)) // users who doesn't have jobs

【讨论】:

  • 我已经阅读了一些关于遵守Hashable 值以及使用set 的内容,但鉴于我是菜鸟,您能否详细说明您将如何使用它们?我完全准备好清理和简化我的代码了。
【解决方案4】:

找到this answer后,我就开始工作了。

我的代码:

func checkIfAllUsersHaveDailyJobs() -> Bool {
    var tempArray = [String]()
    for job in self.dailyJobs {
        for user in self.users {
            if job.assigned == user.firstName {
                print(user.firstName,"has the job:",job.assigned)
                tempArray.append(user.firstName)
            }
        }
    }
    print(tempArray.count)

    for user in self.users {
        if !tempArray.contains(user.firstName) {
            return false
        }
    }
    return true
}

【讨论】:

    猜你喜欢
    • 2020-11-18
    • 1970-01-01
    • 2012-03-28
    • 2019-05-05
    • 2021-06-04
    • 2013-03-27
    相关资源
    最近更新 更多