使用函数式编程将嵌套的字符串数组转换为嵌套的双精度数组

时间:2016-11-14 14:45:10

标签: ios swift functional-programming swift3

我想将嵌套的字符串数组转换为嵌套的双精度数组

示例:

let Strings = [["1.1", "1.2"],["2.1", "2.2"]]

let Doubles = [[1.1, 1.2],[2.1, 2.2]]

我试过

let Doubles = Strings.flatMap(){$0}.flatMap(){Double($0)}

但是在这种情况下我获得了一个double值数组,如何保持这个数组的嵌套?

修改

您是否还可以详细说明为什么不两次使用map()或两次使用flatMap()?为什么正确的方法是使用map,然后使用flatMap

4 个答案:

答案 0 :(得分:2)

在第一个转换中,您应该使用map而不是flatMap,如下所示:

let doubles = Strings.map { $0.flatMap {Double($0)} }

答案 1 :(得分:2)

让我们尝试解决问题。数组有一个map()方法

class FoodItem
{
    string _name;       
    int _numberserved;

    public FoodItem(string name)
    {
        _name = name;
        _numberserved = 0;
    }
    public FoodItem(string name, int numberserved)
    {
        _name = name;
        NumberServed = numberserved;
    }

    public string Name
    {
        get
        {
            return _name;
        }
    }

    public int NumberServed
    {
        get
        {
            return _numberserved;
        }
        set
        {
            if (value > 4)
            {
                _numberserved = 4;
            }
            else
            {
                _numberserved = value;
            }
        }
    }
}    

通过转换每个元素来创建一个新数组,并且a flatMap()方法

/// Returns an array containing the results of mapping the given closure
/// over the sequence's elements.
public func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]

类似但忽略了映射到/// Returns an array containing the non-`nil` results of calling the given /// transformation with each element of this sequence. public func flatMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] 的元素 关闭。

还有另一个flatMap()方法

nil

将每个元素转换为序列并连接 结果

您的代码调用第二个/// Returns an array containing the concatenated results of calling the /// given transformation with each element of this sequence. public func flatMap<SegmentOfResult : Sequence>(_ transform: (Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Iterator.Element] 方法来展平 数组到一个维度,然后是第一个flatMap()方法 将字符串转换为数字。

转换数组(或一般的序列)的第一个候选者是flatMap(),那个 适用于嵌套数组:

map()

结果是选项的嵌套数组,因为转换 浮点值可能会失败。如何解决?

强行打开(通常不推荐):

let strings = [["1.0", "2.0"],["3.0", "4.0"]]
let doubles = strings.map { $0.map { Double($0) }}
print(doubles) // [[Optional(1.0), Optional(2.0)], [Optional(3.0), Optional(4.0)]]

如果您拥有已修复的数据并且可以保证,则可以 每个字符串都是有效的浮点值。如果没有,该计划 会崩溃:

let strings = [["1.0", "2.0"],["3.0", "4.0"]]
let doubles = strings.map { $0.map { Double($0)! }}
print(doubles) // [[1.0, 2.0], [3.0, 4.0]]

提供默认值:

let strings = [["1.0", "2.0"],["3.0", "wot?"]]
let doubles = strings.map { $0.map { Double($0)! }}
// fatal error: unexpectedly found nil while unwrapping an Optional value

此处无效字符串映射到let strings = [["1.0", "2.0"],["3.0", "wot?"]] let doubles = strings.map { $0.map { Double($0) ?? 0.0 }} print(doubles) // [[1.0, 2.0], [3.0, 0.0]] ,因此&#34;形状&#34; 数组的保留。但0.0是一个神奇的数字&#34;现在, 我们无法从结果中看出它是否来自有效的 或无效的字符串。

忽略无效字符串。现在0.0开始发挥作用 (第一个版本):

flatMap()

内部let strings = [["1.0", "2.0"],["3.0", "wot?"]] let doubles = strings.map { $0.flatMap { Double($0) }} print(doubles) // [[1.0, 2.0], [3.0]] 返回非零数组 flatMap()值,即忽略所有无效字符串。

优点:由于输入无效,代码无法崩溃, 没有&#34;魔术数字&#34;使用。 可能的缺点:不保留数组形状。

所以选择你的选择!

答案 2 :(得分:1)

试试这样。

let doubles = strings.map { $0.flatMap { Double($0) } }

一个建议变量名称始终以小写字母开头,而不是DoublesStrings,请写为doublesstrings

答案 3 :(得分:1)

鉴于此

CALL ETIME (...)

你可以写

let strings = [["1.1", "1.2"], ["2.1", "2.2"]]

较短版本

如果你想要一个较短的版本(与其他答案略有不同),那么

let doubles: [[Double]] = strings.map { elms -> [Double] in
    return elms.flatMap { Double($0) }
}