Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 从包含第二个数组元素的数组中获取数据_Arrays_Swift_Xcode_Filter - Fatal编程技术网

Arrays 从包含第二个数组元素的数组中获取数据

Arrays 从包含第二个数组元素的数组中获取数据,arrays,swift,xcode,filter,Arrays,Swift,Xcode,Filter,我有一个包含所有用户数据的数组“users”,第二个数组“userid”包含用户id。我必须使用“userid”数组从“users”数组中提取用户 我想要的结果数组是: [User(name: "b", id: 2), User(name: "c", id: 3), User(name: "b", id: 2), User(name: "d", id: 5)] 因此,它可以根据“userid”中的数据拥有重复的数据 现在我尝试使用高阶函数过滤器: let result = users.f

我有一个包含所有用户数据的数组“users”,第二个数组“userid”包含用户id。我必须使用“userid”数组从“users”数组中提取用户

我想要的结果数组是:

[User(name: "b", id: 2),
 User(name: "c", id: 3),
 User(name: "b", id: 2),
 User(name: "d", id: 5)]
因此,它可以根据“userid”中的数据拥有重复的数据

现在我尝试使用高阶函数
过滤器

let result = users.filter { (user) -> Bool in
    return userIds.contains(user.id)
}
但这会删除重复数据,输出为:

[User(name: "b", id: 2),
 User(name: "c", id: 3),
 User(name: "d", id: 5)]
我尝试的一种方法是使用for循环:

var result = [User]()

for i in userIds {
    result.append(users.filter({ $0.id == i }).first!)
}

这提供了所需的输出,但如果有更好的方法,请提出建议。

在挖掘更多信息后,借助本博客:

我试着这样做:

let results = userIds.compactMap { (int) -> User? in
    var matchedUser: User?
    if users.contains(where: { (user) -> Bool in
        if user.id == int {
            matchedUser = user
        }
        return user.id == int
    }) {
        return matchedUser
    }
    return nil
}
在操场上我检查了执行代码的次数:


与“for”循环相比,计数似乎更少。

您可以使用
首先(其中:)
搜索
用户来解决此问题:

let result = userIds.compactMap { desiredDataValue in
    users.first(where: { $0.id == desiredDataValue })
}
但是,如果您经常这样做,那么如果您构建了一个允许通过“id”值快速查找的数据结构,可能会加快速度。你应该自己比较一下表现,看看你做得是否足够/频繁,是否值得:

let dictsByData = Dictionary(uniqueKeysWithValues:
    users
        .lazy
        .map { dict in
            (key: dict.id, value: dict)
        }
)

let result = userIds.compactMap { desiredDataValue in dictsByData[desiredDataValue]! }
result.forEach { print($0) }

对我来说,循环似乎是一个很好的解决方案。这不是关于我的过滤,而是使用请求(array2)从源(array1)获取。谢谢你的建议@JoakimDanielson。请看我添加的答案。对于
array1
,您可能应该使用structs而不是dicts。否则,您将陷入强制转换、类型错误和崩溃的无底深渊。@Alexander Monica:它只是项目中的struct。为了提问,我在操场上做了一个示例。谢谢你。我喜欢创建数据结构的想法,它很快。除了一件事,我使用的是
compactMap
而不是
map
@Amit,我不建议这样做。我知道,
compactMap
可能会让人觉得你在“正确处理选项”,因为你看不到任何
。但实际上,你所做的是把一个明显的失败(崩溃)变成一个微妙的无声失败(结果中缺少元素)。有时这可能是合适的,但我认为最好是强制展开(如果您确定
array1
中的值始终与
array2
中的值匹配),或者将
nil
保留在适当的位置,稍后再处理。是的,您是对的。但是,array1始终与array2中的值匹配。但在集成到项目中之前,我仍将检查这两种场景。再次感谢你,老兄。还有一件事,你知道对这个问题投反对票的原因吗?@Amit我不知道,但是它在质量控制方面有很多问题。使用
[String:Any]
dicts在结构/类对象更合适的位置,使用像
array1
array2
这样毫无希望的非描述性名称,以及一些英语语法问题
let dictsByData = Dictionary(uniqueKeysWithValues:
    users
        .lazy
        .map { dict in
            (key: dict.id, value: dict)
        }
)

let result = userIds.compactMap { desiredDataValue in dictsByData[desiredDataValue]! }
result.forEach { print($0) }