for with optional collection?


(Rick M) #1

Is there any concise way to write the following?

if let collection = someOptionalCollection
{
    for item in collection
    {
    }
}

I can imagine more complicated things, too:

if let collection = someOptionalCollection as? [SomeType]
{
    for item in collection
    {
    }
}

It would be nice to be able to just attempt to iterate on an optional collection (or Sequence?) and not have to write the enclosing if block

Thanks!

···

--
Rick Mann
rmann@latencyzero.com


(Marco S Hyman) #2

someOptionalCollection?.map {
    /* do something with $0 /*
}

···

On Feb 9, 2017, at 1:26 PM, Rick Mann via swift-users <swift-users@swift.org> wrote:

Is there any concise way to write the following?

if let collection = someOptionalCollection
{
   for item in collection
   {
   }
}


(Jeff Kelley) #3

You can do something like this:

someOptionalCollection?.forEach { item in
  item.doSomething()
}

Or this:

(someOptionalCollection as? [SomeType])?.forEach { item in
  item.doSomething()
}

Jeff Kelley

SlaunchaMan@gmail.com | @SlaunchaMan <https://twitter.com/SlaunchaMan> | jeffkelley.org <http://jeffkelley.org/>

···

On Feb 9, 2017, at 4:26 PM, Rick Mann via swift-users <swift-users@swift.org> wrote:

Is there any concise way to write the following?

if let collection = someOptionalCollection
{
   for item in collection
   {
   }
}

I can imagine more complicated things, too:

if let collection = someOptionalCollection as? [SomeType]
{
   for item in collection
   {
   }
}

It would be nice to be able to just attempt to iterate on an optional collection (or Sequence?) and not have to write the enclosing if block

Thanks!

--
Rick Mann
rmann@latencyzero.com


(Tino) #4

Is there any concise way to write the following?

if let collection = someOptionalCollection
{
   for item in collection
   {
   }
}

I've been thinking about that lately, but haven't had the time to look wether someone on evolution already proposed a "for in?"-loop…

Imho the "forEach" solution is flawed, because you can't break the loop, and the "?? []" isn't perfect either:
I hope the compiler can optimise so that the assembly is as fast as the "if let" solution, but even if this is the case, it is not obvious for a human reader.

This

extension Optional where Wrapped: Sequence {
  var elements: [Wrapped.Iterator.Element] {
    switch (self) {
    case .none:
    return []
    case .some(let o):
    return Array(o)
    }
  }
}

let test: [Int]? = nil
for i in test.elements {
  print(i)
}

looks nice to me (except the return type — I guess there are better options), but I don't expect that the compiler can do much to optimise it.

for i in? test {
  print(i)
}

Imho looks even better, but this would need an extension of the language itself…


(Maxim Veksler) #5

How about:

let c: [Int]? = nil

c.map { for e in $0 { print(e) } }

// 1

// 2

// 3

Based on
https://developer.apple.com/reference/swift/optional/1539476-map#discussion

···

On Thu, Feb 9, 2017 at 11:26 PM Rick Mann via swift-users < swift-users@swift.org> wrote:

Is there any concise way to write the following?

if let collection = someOptionalCollection
{
    for item in collection
    {
    }
}

I can imagine more complicated things, too:

if let collection = someOptionalCollection as? [SomeType]
{
    for item in collection
    {
    }
}

It would be nice to be able to just attempt to iterate on an optional
collection (or Sequence?) and not have to write the enclosing if block

Thanks!

--
Rick Mann
rmann@latencyzero.com

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Saagar Jha) #6

Or even

for item in someOptionalCollection ?? [] {
  item.doSomething()
}

Saagar Jha

···

On Feb 9, 2017, at 1:30 PM, Jeff Kelley via swift-users <swift-users@swift.org> wrote:

You can do something like this:

someOptionalCollection?.forEach { item in
  item.doSomething()
}

Or this:

(someOptionalCollection as? [SomeType])?.forEach { item in
  item.doSomething()
}

Jeff Kelley

SlaunchaMan@gmail.com <mailto:SlaunchaMan@gmail.com> | @SlaunchaMan <https://twitter.com/SlaunchaMan> | jeffkelley.org <http://jeffkelley.org/>

On Feb 9, 2017, at 4:26 PM, Rick Mann via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Is there any concise way to write the following?

if let collection = someOptionalCollection
{
   for item in collection
   {
   }
}

I can imagine more complicated things, too:

if let collection = someOptionalCollection as? [SomeType]
{
   for item in collection
   {
   }
}

It would be nice to be able to just attempt to iterate on an optional collection (or Sequence?) and not have to write the enclosing if block

Thanks!

--
Rick Mann
rmann@latencyzero.com <mailto:rmann@latencyzero.com>_______________________________________________

swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Rick M) #7

Thanks, this is probably the closest. Sadly I can't seem to test downcasting because Playgrounds just stop working, with no feedback, for this code:

class Foo
{
  init(_ inVal: String) { self.name = inVal }
  
  var name: String
  var desc: String { get { return "Foo \(name)" } }
}

let f = Foo("foo")

class Bar : Foo
{
  var desc: { return "Bar \(name)" }
}

let stuff: [Foo]?// = [Bar("foo"), Bar("bar"), Bar("baz")]
for item in (stuff as? [Bar]) ?? []
{
}

···

On Feb 9, 2017, at 13:31 , Saagar Jha <saagar@saagarjha.com> wrote:

for item in someOptionalCollection ?? [] {
  item.doSomething()
}

--
Rick Mann
rmann@latencyzero.com


(David Hart) #8

someOptionalCollection?.forEach { item in
}

···

On 9 Feb 2017, at 22:48, Marco S Hyman via swift-users <swift-users@swift.org> wrote:

On Feb 9, 2017, at 1:26 PM, Rick Mann via swift-users <swift-users@swift.org> wrote:

Is there any concise way to write the following?

if let collection = someOptionalCollection
{
  for item in collection
  {
  }
}

someOptionalCollection?.map {
   /* do something with $0 /*
}

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Maury Markowitz) #9

Oh, yes please!

Please post on evolution.

···

On Feb 10, 2017, at 10:04 AM, Tino Heth via swift-users <swift-users@swift.org> wrote:

for i in? test {
  print(i)
}

Imho looks even better, but this would need an extension of the language itself…


(Rick M) #10

I love the idea of for in? (Or even for? In). You should pitch that to evolution.

···

Sent from my iPhone

On Feb 10, 2017, at 07:04, Tino Heth <2th@gmx.de> wrote:

Is there any concise way to write the following?

if let collection = someOptionalCollection
{
   for item in collection
   {
   }
}

I've been thinking about that lately, but haven't had the time to look wether someone on evolution already proposed a "for in?"-loop…

Imho the "forEach" solution is flawed, because you can't break the loop, and the "?? []" isn't perfect either:
I hope the compiler can optimise so that the assembly is as fast as the "if let" solution, but even if this is the case, it is not obvious for a human reader.

This

extension Optional where Wrapped: Sequence {
  var elements: [Wrapped.Iterator.Element] {
    switch (self) {
    case .none:
    return []
    case .some(let o):
    return Array(o)
    }
  }
}

let test: [Int]? = nil
for i in test.elements {
  print(i)
}

looks nice to me (except the return type — I guess there are better options), but I don't expect that the compiler can do much to optimise it.

for i in? test {
  print(i)
}

Imho looks even better, but this would need an extension of the language itself…


(Jacob Bandes-Storch) #11

To me it would seem more logical as "for x in array? { }" — to parallel
"for case let x? in array { }"

···

On Fri, Feb 10, 2017 at 1:03 PM, Rick Mann via swift-users < swift-users@swift.org> wrote:

I love the idea of for in? (Or even for? In). You should pitch that to
evolution.

Sent from my iPhone

On Feb 10, 2017, at 07:04, Tino Heth <2th@gmx.de> wrote:

Is there any concise way to write the following?

if let collection = someOptionalCollection
{
   for item in collection
   {
   }
}

I've been thinking about that lately, but haven't had the time to look
wether someone on evolution already proposed a "for in?"-loop…

Imho the "forEach" solution is flawed, because you can't break the loop,
and the "?? []" isn't perfect either:
I hope the compiler can optimise so that the assembly is as fast as the
"if let" solution, but even if this is the case, it is not obvious for a
human reader.

This

extension Optional where Wrapped: Sequence {
var elements: [Wrapped.Iterator.Element] {
switch (self) {
case .none:
return []
case .some(let o):
return Array(o)
}
}
}

let test: [Int]? = nil
for i in test.elements {
print(i)
}

looks nice to me (except the return type — I guess there are better
options), but I don't expect that the compiler can do much to optimise it.

for i in? test {
print(i)
}

Imho looks even better, but this would need an extension of the language
itself…

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


For loops with optional arrays, is there a better, less wordy way?
(Rick M) #12

How would you write

for x in array as? <something>

With parentheses? I like "in?" because it mimics "as?".

···

Sent from my iPhone

On Feb 10, 2017, at 13:57, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

To me it would seem more logical as "for x in array? { }" — to parallel "for case let x? in array { }"

On Fri, Feb 10, 2017 at 1:03 PM, Rick Mann via swift-users <swift-users@swift.org> wrote:
I love the idea of for in? (Or even for? In). You should pitch that to evolution.

Sent from my iPhone

On Feb 10, 2017, at 07:04, Tino Heth <2th@gmx.de> wrote:

Is there any concise way to write the following?

if let collection = someOptionalCollection
{
   for item in collection
   {
   }
}

I've been thinking about that lately, but haven't had the time to look wether someone on evolution already proposed a "for in?"-loop…

Imho the "forEach" solution is flawed, because you can't break the loop, and the "?? []" isn't perfect either:
I hope the compiler can optimise so that the assembly is as fast as the "if let" solution, but even if this is the case, it is not obvious for a human reader.

This

extension Optional where Wrapped: Sequence {
  var elements: [Wrapped.Iterator.Element] {
    switch (self) {
    case .none:
    return []
    case .some(let o):
    return Array(o)
    }
  }
}

let test: [Int]? = nil
for i in test.elements {
  print(i)
}

looks nice to me (except the return type — I guess there are better options), but I don't expect that the compiler can do much to optimise it.

for i in? test {
  print(i)
}

Imho looks even better, but this would need an extension of the language itself…

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users