快速连续数组的数据结构

时间:2019-01-02 09:04:02

标签: arrays swift data-structures

我有两个连续使用的数组。

var pinnedMessage: [Message]
var normalMessage: [Message]

第一

我将固定消息添加到第一个数组,将普通消息添加到第二个数组。我总是同时使用两个数组。因此,当我使用它们时,我要创建一个新数组,首先附加固定的消息,然后追加普通消息。

var newArray: [Message] = []
newArray.append(pinnedMessage)
newArray.append(normalMessage)

第二

另一种方法是,我将两条消息都放在一个数组中,然后根据它们的isPinned属性对其进行排序。

GlobalArray.sort { $0.isPinned && !$1.isPinned }

我还应该知道第一条普通邮件的索引在哪里。所以我也有一个变量。

我不认为这些想法是否可行。我应该使用链表还是其他数据结构?

3 个答案:

答案 0 :(得分:1)

您可以更改访问数组的方式,而不是使用列出的任何替代方法。您可以使用辅助函数(以闭包作为参数)来处理数组中的每个元素:

struct Message {
    let text: String
}

let pinnedMessages: [Message] = [Message(text: "I'm pinned"), Message(text: "I'm also pinned")]
let normalMessages: [Message] = [Message(text: "I'm normal"), Message(text: "I'm also normal")]
@inline(__always)
func foreachMessage(function: (Message) throws -> ()) rethrows {
    try pinnedMessages.forEach(function)
    try normalMessages.forEach(function)
}

如果您还需要了解消息的类型,则应该单独处理数组而不使用帮助函数,或者让闭包接受另一个参数:

enum MessageType {
    case pinned
    case normal
}


@inline(__always)
func foreachMessage(function: (Message, MessageType) throws -> ()) rethrows {
    try pinnedMessages.forEach { try function($0, .pinned) }
    try normalMessages.forEach { try function($0, .normal) }
}
foreachMessage { message in
    print(message)
}

foreachMessage { message, type in
    print(message, type)
}

使用这种方法可使您摆脱串联两个数组的缺点:内存和性能开销。

如果将这些消息显示为好像在一个数组中,则第一条普通消息的索引将仅位于pinnedMessages数组中最后一条消息的索引之后。 pinnedMessages.count等于该数组的最后一个索引+ 1,等于普通邮件的第一个索引。

答案 1 :(得分:0)

我已经创建了与您签出此代码相同的情况。

struct Message {
    var isPinned: Bool
}

var pinnedArray: [Message] = [Message(isPinned: true),Message(isPinned: true),Message(isPinned: true),Message(isPinned: true)]
var notPinnedArray: [Message] = [Message(isPinned: false),Message(isPinned: false),Message(isPinned: false),Message(isPinned: false)]

var sortedArray: [Message]  = pinnedArray + notPinnedArray // this will put pinned Array first then add the normal one after it so it would be [true, true, ture, true, false, false, false, false ]
var indexForFirstNormalMessage = pinnedArray.count //index for the first normal message is the count of the pinnedArray because array indexing starts at 0 and counting starts at 1 so  using the count of the pinned array as index in the sorted one, would get you the first normal message index.
print(indexForFirstNormalMessage) // 4

sortedArray.forEach {message in
    print(message)
}
/* Message(isPinned: true)
 Message(isPinned: true)
 Message(isPinned: true)
 Message(isPinned: true)
 Message(isPinned: false)
 Message(isPinned: false)
 Message(isPinned: false)
 Message(isPinned: false)*/

答案 2 :(得分:0)

您可以创建一个包含连续添加固定消息和普通消息的数组,并在firstIndex(where:)上使用 Swift 4.2 Collections方法来获取普通消息的第一个索引

struct Message {
    let isPinned: Bool
}

let pinned = [Message(isPinned: true), Message(isPinned: true), Message(isPinned: true)]
let normal = [Message(isPinned: false), Message(isPinned: false), Message(isPinned: false)]
let sortedArray = pinned + normal

if let firstIndex = sortedArray.firstIndex(where: { $0.isPinned == false }) {
    print(firstIndex)
}

如果您在UIViewController中进行操作,则可以在didSet上使用sortedArray观察者来设置正常消息的firstIndex

class ViewController: UIViewController {

    var normalPinFirstIndex: Int?

    var sortedArray: [Message] = [] {
       didSet {
            if !sortedArray.isEmpty {
                normalPinFirstIndex = sortedArray.firstIndex(where: { $0.isPinned == false })
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        let pinned = [Message(isPinned: true), Message(isPinned: true), Message(isPinned: true)]
        let normal = [Message(isPinned: false), Message(isPinned: false), Message(isPinned: false)]
        sortedArray =  pinned + normal
        if let firstIndex = normalPinFirstIndex {
            print(firstIndex)
        }
    }
}