I like the above code because it is concise and gives nice output. However, if I wanted to do something similar for the moons in our Solar System, I run into the problem that only some moons have images. If I run the following line of code, I get a somewhat sloppy output with Missing Image errors embedded.

I was wondering if there is a simple way to Map over a list of data conditionally? That is, if an element in a list does not meet a specific condition then skip over it. Note that I'm looking to avoid an explicit loop with an If construct. I really don't mind using a loop with an If statement, but I was curious if there was a concise idiom that anyone could shed some light on.

The more I look at these answers the more I see just how much experience you guys have. Seriously a dizzying array of different approaches. I've learned SOO much more looking up the strange code I've seen here than what I originally came here to learn :D Thanks again everyone!
–
Alfred FazioFeb 3 '12 at 5:18

You're welcome, and welcome to the community.
–
rcollyerFeb 3 '12 at 14:10

I'd be curious to see a more "concise" piece of code. Alternatively instead of using exact pattern _[_, _Image] you could just use _Image and specify all levels in expression to search for that pattern:

Thank you for posting this, Vitaliy. I've learned a lot from your example. I would say that this answer comes in second place only because it requires more computation than the answer provided by David Skulsky. Mr. Skulsky's answer avoids running Map on elements unless they meet the criteria. In your answer all elements are computed and then filtered. Either way, this is a great answer. Thank you!
–
Alfred FazioFeb 3 '12 at 5:24

1

+1 for Vitaly's answer because his approach only calls AstronomicalData[#,"Image"] once for each moon, whereas my approach calls it twice.
–
David SkulskyFeb 3 '12 at 5:32

@J.M. I was rather referring to ` _Missing` part - it won't delete because Labeled wrapped around ` _Missing`. You cracked me up with the "idiom" joke ;)
–
Vitaliy KaurovFeb 3 '12 at 5:33

Still, the pattern can be changed accordingly. Or, use DeleteCases[] before any further processing's done. :) Anyway, at least you got my intent.
–
Ｊ. Ｍ.Feb 3 '12 at 5:48

This is absurd in how it looks, but in this case I don't think skipping over the missing images is necessary. Instead, we are going to redefine what Missing means by attaching an upvalue to it using UpSetDelayed (^:=), as follows

and returns what you expect. Block allows you to temporarily redefine what a Symbol means, and in this case, I set Missing["NotAvailable"] to return a Sequence[]. An empty sequence has the special property that it will truncate a list it is found in, for example

{a, b, Sequence[], c}

returns

{a, b, c}

So, by redefining Missing to return an empty Sequence, the code shortens the list for you.

Also, here's a purely functional approach that does not require accessing the database more than twice: once for the list of the moons and once for the image.

In situations like your, where you don't know the number of elements in your result in advance, two functions become very handy: Reap and Sow. The approach is to Sow an element you want in your list deep inside the code and to Reap them at the outside.

Note that Reap gives you two lists, the first one is your original Table result which contains Null when a number is not prime and the last list contains only the Sowed elements. Therefore, your moons are extracted by

@Mr.Wizard, you lost me there, you'll have to explain _~_~_Missing to me.
–
RunnyKineApr 15 '13 at 0:48

It's equivalent to _[_, _Missing] but in infix form, and without the spacing needed to make that form readable. I don't recommend it in practice! For another humorous pattern see this. Frightening, isn't it? :o)
–
Mr.Wizard♦Apr 15 '13 at 0:51

Mathematica is a registered trademark of Wolfram Research, Inc. While the mark is used herein with the limited permission of Wolfram Research, Stack Exchange and this site disclaim all affiliation therewith.