What is a functional style replacement for this cycle?

nums = [2 5 3 7] result = [] result.push {x:nums[0]} for n in nums.slice(1) result.push {n:n + result[-1].x} log result # [{x:2} {x:7} {x:10} {x:17}] 

It is difficult to express functionally using the map function, because each element depends on the previous element. What is the correct functional solution for this algorithm?

+4
source share
6 answers

The simplest way that I know avoids performance locks, variables, extra overhead, and global variables:

 result= [2, 5, 3, 7].map(function(a){ return { x: this[0]+=a }; }, [0]); 

JS provides the rarely used 2.map () parameter to store any state that is required between iterations.

Most likely, this does not work out easier, but I don’t know the coffee, sorry ...

EDIT: demo of a bilingual demo (js + cs): http://pagedemos.com/maptranforms/

+18
source

What you are describing is a scan: a summary that also returns intermediate results. Using scan1 from prelude.ls:

 nums = [2 5 3 7] scan1 (+), nums |> map ((num) -> { x : num }) # => [{x: 2}, {x: 7}, {x: 10}, {x: 17}] 

If you do not need objects inside the array and only add-ons with intermediate results are needed, you can generally refuse the operation with the map and just write:

 scan1 (+), [2 5 3 7] # => [2, 7, 10, 17] 

scan1 documenation .

+8
source

You need to save status information somewhere. This is where JavaScript closes, doing the job:

 var nums = [2, 5, 3, 7]; var result = nums.map( (function() { var lastX = 0; return function(n) { return {x : (lastX += n)}; } }()) ); // result is [{x:2} {x:7} {x:10} {x:17}] 
+3
source

Javascript

Keep the current total counter and just add a new number every time:

 var nums = [2,5,3,7]; var createObject = function(nums){ var result = [], total = 0; for(var i = 0; i < nums.length; i++){ total += nums[i]; result.push({"x": total}); } return result; }; 

JSFIDDLE

+2
source

dandavis Reply in coffeescript:

 nums.map ((x)->{x: @[0] += x}), [0] 

option that might be a little clearer

 nums.map ((x)->{x: @accum += x}), {accum:0} 

using coffeescript insight (and the same battery idea)

 accum = 0; z = ({x: accum += i} for i in nums) 
+2
source
 map (-> {x:it}) <| (fold ((acc, a) -> acc ++ [a + ((last acc) ? 0)]), []) <| [2, 5, 3, 7] 
+1
source

Source: https://habr.com/ru/post/1485114/


All Articles