0

I have two arrays, which are used consecutively.

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

First

I add the pinned messages to the first array and normal ones to the second. bu I always use both arrays Consecutive. so when I use them I make a new array, first append pinned messages then normal messages.

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

Second

Another way is that I put both messages in one array and then sort them based on if their isPinned property.

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

I also should know where is the index of first normal message. so I have a variable for that too.

I don't think if these ideas are ok. Should I use linked list or other data structure?

3
  • 1
    so you want to use them pinned one, then not pinned .. and so on ? Commented Jan 2, 2019 at 9:08
  • 3
    What's your goal with theses Message arrays? You could create a computed property in GlobalArray that concatenate them and return them: var allMessages: [Message] { return pinnedMessages + normalMessages } Commented Jan 2, 2019 at 9:09
  • @7bebMrto Yes. I always show the pinned one first then normal ones Commented Jan 2, 2019 at 9:10

3 Answers 3

1

Rather than using any of the alternatives you've listed, you could instead alter the way that you access your arrays. You can use a helper function, taking a closure as an argument, to process each element in the arrays:

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)
}

If you also need to know the type of the message, you should either process the arrays individually, without a helper function, or let your closure take another argument:

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)
}

Using this kind of method, frees you from the disadvantage of concatenating the two arrays: memory and performance overhead.

If you're displaying these messages as if they're in one array, the index of the first normal message, will simply be after the index of the last message in the pinnedMessages array. pinnedMessages.count will be equal to that array's last index + 1, equalling the first index of the normal messages.

Sign up to request clarification or add additional context in comments.

4 Comments

Holy cow, this seems like an absolute overkill
@LinusGeffarth Then holy it is. What's so overkill about it?
Idk, it looks like OP would be ok with just doing let messages = pinned + normal.
@LinusGeffarth Concatenating arrays is not always the best solution. This solution is better in terms of performance and memory footprint, especially if Message would contain large amounts of data, like image(s) and long text.
0

I have created the same situation you are in check out this code.

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)*/

Comments

0

You can create a single array with both pinned and normal messages added consecutively and use Swift 4.2 firstIndex(where:) method on Collections to get the first index of normal message

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)
}

if you're doing it in UIViewController then can use didSet observer on the sortedArray to set the firstIndex of normal message

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)
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.