3

Why are there MapThread and MapIndexed but no analogous functions for Scan?

What is the recommended way to Scan over a pair of datasets (ScanThread), or over an ordered dataset (ScanIndexed)?


Edit

The reason I don't want to use Map is because it builds up an expression, which wastes memory and time.

I need to apply function(s) f, g with no output (only side effects) on lists of entries:

data1 = {a,b,c,d,e};
data2 = {s,t,u,v,w};

(*MapThread correctly calls f[a,s], f[b,t], but builds up an expression*)
MapThread[f, {data1, data2}] 

(*MapIndexed calls g[a,{1}], g[b,{2}], but builds up an expression*)
MapIndexed[g, data1]

I only want to scan over these entries, without wasting resources and time.

QuantumDot
  • 19,601
  • 7
  • 45
  • 121
  • 1
    You can use Map* versions and just add ; it will be close, those rules apply: 46238 – Kuba Jul 24 '17 at 16:08
  • Do you have a use case in which the Scan behavior is preferable to Map? – MarcoB Jul 24 '17 at 16:09
  • I think you owe us a better formulation of this question. Give us two example datasets and an example of a query which would require the function you propose. – m_goldberg Jul 24 '17 at 16:09
  • @Kuba Map builds up an expression which wastes time and memory; I need Scan (see edit). – QuantumDot Jul 24 '17 at 16:27
  • @MacroB Map builds up an expression which wastes time and memory; I need Scan (see edit) – QuantumDot Jul 24 '17 at 16:27
  • 5
    ScanIndexed is on the road map, not sure when it will appear though. – Daniel Lichtblau Jul 24 '17 at 16:28
  • @m_goldberg Added edit. – QuantumDot Jul 24 '17 at 16:28
  • 1
    @DanielLichtblau Ok that's good to know. In the meantime, what is the recommended way to mimic a ScanThread and ScanIndexed? – QuantumDot Jul 24 '17 at 16:31
  • 2
    Your edit isn't very helpful. We all know what Map and MapThread do. What we need are examples giving executable code. Real data and actual functions for which scanning would be better than mapping. – m_goldberg Jul 24 '17 at 16:34
  • @m_goldberg Ok thanks; I guess I'm basically directing this question to those who already understand why and when Scan is preferable to Map; I just need to know from them what to do in those situations if I need the threaded and indexed versions of these functions. – QuantumDot Jul 24 '17 at 16:38
  • 4
    @QuantumDot, I suspect that @m_goldberg is in fact familiar with Scan vs. Map use cases, but he is asking you as the author of the question to provide us with an actual code case where one can appreciate a significant difference between Scan and Map, rather than just the perception of waste, so we can evaluate different possible solutions in terms of time and memory consumption. If you don't provide that, you will only get answers from those that have had the problem, and solved it, which may rather significantly reduce your chances. – MarcoB Jul 24 '17 at 18:18
  • 2
    There is the undocumented GeneralUtilities`ScanIndexed, but it is just a high-level wrapper that delegates to Do, Scan or sometimes even MapIndexed. – WReach Jul 24 '17 at 19:17
  • 1
    I agree with other comments that examples of your real life data and function would be useful, so we could do some meaningful benchmarks. For simplest case of indexed scanning you could just manually increment index: Module[{i = 0}, Scan[f[#, {++i}] &, data1]] – jkuczm Jul 24 '17 at 19:28
  • @WReach Interesting find! – QuantumDot Jul 24 '17 at 20:00
  • @jkuczm Yes, that is a very helpful alternative; I think I'll use it. Would you kindly add that as an answer? (Also I thought for ScanThread the following Scan[f@@#&, Transpose[{data1,data2}]]; what do you think?) – QuantumDot Jul 24 '17 at 20:03
  • @QuantumDot Transpose[{data1,data2}] creates new list of pairs, so most likely MapThread[f, {data1, data2}]; or MapThread[(f@##; 0) &, {data1, data2}]; will use same or less memory while being faster. – jkuczm Jul 24 '17 at 20:20
  • @jkuczm Oh, ok; thanks. – QuantumDot Jul 24 '17 at 20:21

0 Answers0