简体   繁体   English

快速筛选并映射结构数组

[英]Swift Filter and Map over array of structs

I may have this really wrong. 我可能真的错了。 Noob. 菜鸟。 I've recreated what I'm doing in a playground type environment here. 我已经在这里重新创建了我在游乐场类型环境中所做的工作。 Basically the sender is a slider within a UITableView of other sliders. 基本上,发送者是其他滑块的UITableView中的滑块。 The myData is the underlying data. myData是基础数据。 I want to perform a calculation to all the items of the underlying data EXCEPT the one which corresponds to the sender item. 我要对基础数据的所有项目执行计算,除了与发送方项目相对应的项目。 I have no idea if my closure syntax is correct. 我不知道我的关闭语法是否正确。 This is the first time I'm creating one. 这是我第一次创建一个。

// sender comes over as a struct
struct myStruct {
    var tag: Int = 0
    var value: Float = 0
}
let sender = myStruct(tag: 1, value: 199)

// some vars for the calculation
let globalTotal: Float = 597
let globalAnotherTotal: Float = 0

// an array of data structs
struct myDataStruct {
    var name: String = ""
    var value: Float = 0
}
var myData: [myDataStruct] = []
myData.append(myDataStruct(name: "Tom", value: 45.0))
myData.append(myDataStruct(name: "Dick", value: 16.4))
myData.append(myDataStruct(name: "Harry", value: 12.3))

// a closure to do the calculation
var calcOtherVals: (Float, Float) -> (Float) = { (startVal, senderStartVal) in

    let remainingStartVals = globalTotal - senderStartVal
    let remainingNewVal = globalTotal - sender.value - globalAnotherTotal

    let endVal = ((startVal * (100 / remainingStartVals)) / 100) * remainingNewVal

    return endVal
}

// now need to perform calcOtherVals on all the .value floats in myData EXCEPT the element at position sender.tag hopefully using filter and map

So basically I'm trying to use filter and map and the calcOtherVals closure to edit the array of structs in place. 因此,基本上我正在尝试使用过滤器和映射以及calcOtherVals闭包来就地编辑结构数组。 I can do this with conditionals and loops and calcOtherVals as a function no problem. 我可以使用条件和循环以及calcOtherVals作为函数来完成此操作。 Just hoping to do it more elegantly. 只是希望做得更优雅。

QUESTION: As in the code comment, I need to perform calcOtherVals on all the .value floats in myData EXCEPT the element at position sender.tag . 问题:如代码注释中所述,我需要对calcOtherVals中所有.value浮点数执行calcOtherVals ,除了sender.tag位置的元素。 How? 怎么样?

So as I understood you need to filter your array something like 因此,据我了解,您需要像这样过滤数组

let filteredData = myData.filter({$0.tag != sender.tag})

then you use reduce to calculate 然后你用reduce来计算

let sumAll = filterdData.reduce(0, {$0.value + $1.value})
myData.enumerated().flatMap { (index, element) in return index != sender.tag ? calcOtherVals (element.value) : nil }

Few bits of swift magic here. 这里很少有快速的魔术。 Firstly enumerate() returns an array of tuples containing the element, and the index of said element. 首先, enumerate()返回一个元组数组,其中包含该元素以及该元素的索引。

Next flatMap() . 下一个flatMap() This is essentially map but it ignores any transform that resolves to nil. 这本质mapmap但是它忽略任何解析为nil的变换。 Great for converting from an optional array to a flat array, and also great if you wish to do a map+filter operation such as this. 非常适合从可选数组转换为平面数组,如果您希望执行这样的map + filter操作,也非常有用。

-- Updated -- - 更新 -

If you're comfortable with implicit arguments, you can reduce it further: 如果您对隐式参数感到满意,则可以进一步减少它:

myData.enumerated().flatMap { $0.offset != sender.tag ? calcOtherVals ($0.element.value) : nil }

This Question is Already have an answer, 这个问题已经有答案了,

for better understanding you can review this very good tutorial about map, filter and reduce 为了更好地理解,您可以查看有关地图,过滤和归约的很好的教程

Link:- https://useyourloaf.com/blog/swift-guide-to-map-filter-reduce/ 链接:-https: //useyourloaf.com/blog/swift-guide-to-map-filter-reduce/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM