首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >从Swift中的数组中移除较小的值集

从Swift中的数组中移除较小的值集
EN

Stack Overflow用户
提问于 2016-06-02 23:49:18
回答 3查看 162关注 0票数 2

给定一个由包含整数的数组组成的数组。

代码语言:javascript
代码运行次数:0
运行
复制
[[2], [3], [2, 2], [5], [7], [2, 2, 2], [3, 3]]

在Swift中,什么是最好的方法来删除包含少量具有特定值的元素的数组,并且只保留包含该值的较大数组。

以上输入的结果将是

代码语言:javascript
代码运行次数:0
运行
复制
[[5], [7], [2, 2, 2], [3, 3]]
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-06-03 00:39:15

使用[Int: [Int]]字典跟踪键指定的值的最大数组。

代码语言:javascript
代码运行次数:0
运行
复制
let arrays = [[2], [3], [2, 2], [5], [7], [2, 2, 2], [3, 3]]
var largest = [Int: [Int]]()

for arr in arrays {
    // Get the first value from the array
    if let first = arr.first {

        // current is the count for that key already in dictionary largest
        // If the key isn't found, the nil coalescing operator ?? will
        // return the default count of 0.
        let current = largest[first]?.count ?? 0

        // If our new array has a larger count, put it in the dictionary
        if arr.count > current {
            largest[first] = arr
        }
    }
}

// Convert the dictionary's values to an array for the final answer.   
let result = Array(largest.values)

print(result)  // [[5], [7], [2, 2, 2], [3, 3]]

同样的逻辑可以与reduce一起使用,以便在一行中提供结果:

代码语言:javascript
代码运行次数:0
运行
复制
let result = arrays.reduce([Int: [Int]]()) { var d = $0; guard let f = $1.first else { return d }; d[f] = d[f]?.count > $1.count ? d[f] : $1; return d }.map { $1 }

交替版本

这个版本使用[Int: Int]字典来保存每个键找到的最大数组的计数,然后使用数组构造函数在末尾重新构造数组。

代码语言:javascript
代码运行次数:0
运行
复制
let arrays = [[2], [3], [2, 2], [5], [7], [2, 2, 2], [3, 3]]
var counts = [Int: Int]()

for arr in arrays {
    if let first = arr.first {
        counts[first] = max(counts[first] ?? 0, arr.count)
    }
}

let result = counts.map { [Int](count: $1, repeatedValue: $0) }

print(result)  // [[5], [7], [2, 2, 2], [3, 3]]

同样的逻辑可以与reduce一起使用,以便在一行中提供结果:

代码语言:javascript
代码运行次数:0
运行
复制
let result = arrays.reduce([Int: Int]()) { var d = $0; guard let f = $1.first else { return d }; d[f] = max(d[f] ?? 0, $1.count); return d }.map { [Int](count: $1, repeatedValue: $0) }
票数 2
EN

Stack Overflow用户

发布于 2016-06-03 02:04:17

我正要把我的答案写下来,这时我看到瓦瓦摩的反应是非常相似的。只是因为这是一个有趣的问题,所以我们决定回到这个问题上。因此,我的替代方案几乎肯定要比真空解决方案慢得多,而且不能保持顺序,但我认为这是一个有趣的例子,说明了在Swift中解决类似问题的替代方案。

代码语言:javascript
代码运行次数:0
运行
复制
var items = [[2], [3], [2, 2], [5], [7], [2, 2, 2], [3, 3]]

let reduced = items.sort({
        let lhs = $0.first, rhs = $1.first
        return lhs == rhs ? $0.count > $1.count : lhs < rhs
    }).reduce( [[Int]]()) { (res, items) in
        return res.last?.last != items.last ? res + [items] : res
    }

print(reduced)  // [[2, 2, 2], [3, 3], [5], [7]]

或者如果你想把所有这些都塞在一条线上:

代码语言:javascript
代码运行次数:0
运行
复制
var items = [[2], [3], [2, 2], [5], [7], [2, 2, 2], [3, 3]]

let reduced = items.sort({ let lhs = $0.first, rhs = $1.first; return lhs == rhs ? $0.count > $1.count : lhs < rhs }).reduce([[Int]]()) { $0.last?.last != $1.last ? $0 + [$1] : $0 }

print(reduced)  // [[2, 2, 2], [3, 3], [5], [7]]
票数 1
EN

Stack Overflow用户

发布于 2016-06-03 04:17:15

使用forEach的另一种选择是:

代码语言:javascript
代码运行次数:0
运行
复制
let arrays = [[2],  [2, 2], [5], [7], [2, 2, 2], [3, 3], [3]]
var largest: [Int: [Int]] = [:]

arrays.forEach({
    guard let first = $0.first else { return }
    largest[first] = [Int](count: max($0.count,largest[first]?.count ?? 0), repeatedValue: first)
})
Array(largest.values)  // [[5], [7], [2, 2, 2], [3, 3]]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37603888

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档