I had some C++ code that would determine if any element in a list was selected. A “selected” element is one that has a boolean variable “isSelected” set to be true:
bool bLinkSelected = false; POSITION Position = pConnector->GetLinkList()->GetHeadPosition(); while( Position != 0 ) { CLink* pLink = pConnector->GetLinkList()->GetNext( Position ); if( pLink != 0 ) { if( pLink->IsSelected() ) bLinkSelected = true; break; } }
This is a little ugly because I’m using MFC and the linked lists that it provides. The test for a null pointer is also not really necessary. But the point is that this same sort of thing can be done in Swift in a single line of code.
I first ended up looking at the Swift map() function and then seeing that it wasn’t what I needed, looked at the reduce() function. Somehow I didn’t see the other array processing functions until after I had a line of code that I liked:
let anyLinkSelected = connector.links.reduce( false ) { $0 || $1.isSelected }
This Swift code reduces the array down to a single Bool value and seems fairly self-explanatory. But then I thought that it would be better to search for the selected element in the list, assuming that the Swift first() function would not test all elements, just those ahead of the selected element:
let anyLinkSelected = connector.links.first( where: { $0.isSelected } )?.isSelected ?? false
This is more code and a little unclear because of how it deals with there being no selected elements. But it should be faster on average over the reduce() function call. Then after days of ignoring the problem, or rather a week or two since I don’t work on this stuff all the time, I realized out of the blue that I was using the absolutely wrong function for this… again. This is what I finished with:
let anyLinkSelected = connector.links.contains( where: { $0.isSelected } )
This is exactly the right function for this situation. I had always used the contains() function to see if a specific element is in an array. In this case, it makes sense that it is testing to see if the list contains any selected element. This should be fast and it is also less code than either of the other two choices.
Swift is a powerful language and as I port the Linkage program to the Mac, I’m changing it in interesting ways. I’m sure that I’m making some bad design decisions in an attempt to be clever, but overall, I’m pleased with the results so far.