0

so I'm struggling to understand this code. Can someone please explain how does function move works? Like I watched a lecture about it, but I still don't understand it.

const parse = (point) => {
  return typeof point === "object" ? point : JSON.parse(point);
};
    
const move = (offset) => (point) =>{
  point.x += offset.x;
  point.y += offset.y;
  return point
};
    
const polyline = [
  { x: 0, y: 0 },
  { x: 10, y: 10 },
  '{ "x": 20, "y": 20 }',
  { x: 30, y: 30 },
];
    
    
const offset = move({ x: 10, y: -5 });
const path = polyline.map(parse).map(offset);
console.log({ path });

Here's how it was done previously, and this code is an optimised version of that code:

const shift = (offset, points) => {
    let modifiedPoints = [];
    points.forEach((point) => {
        point = parse(point);
        point.x += offset.x;
        point.y += offset.y;
        modifiedPoints.push(point);
    });
    return modifiedPoints;
};
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Sof
  • 11
  • What's the actual problem? The closure? -> [How do JavaScript closures work?](https://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – Andreas Dec 20 '21 at 13:49
  • 1
    I believe [What is currying](https://stackoverflow.com/questions/36314/what-is-currying) has all the info you need. – trincot Dec 20 '21 at 13:50
  • `move({ x: 10, y: -5 })` returns a function that will, when executed, "move" its argument (a point) 10 pixels right and 5 pixels down. – Andreas Dec 20 '21 at 13:51
  • @trincot - Yeah, I think you're right. – T.J. Crowder Dec 20 '21 at 13:54
  • The key bit here is that `move` **doesn't** move anything, it returns a new function that will move things. (For that reason, it probably should have been giving a different name.). So `const offset = move({ x: 10, y: -5 });` creates and returns a function that will move a point by `x: 10`, `y: -5` if you call it, and stores that function in `offset`. (Again, better naming would have helped here.) The actual moving happens later, when `map` calls `offset` with each point: `const path = polyline.map(parse).map(offset);` – T.J. Crowder Dec 20 '21 at 13:55
  • *"Here's how it was done previously, and this code is an optimised version of that code:"* "Optimized" doesn't really mean anything without saying what it's been optimized *for* (speed? memory consumption? readability? reusability?). :-) By many measures, the "optimized" version here is de-optimized. It's harder to read if you're not well-versed in functional programming (and it's not really FP, it modifies points directly rather than creating new ones), takes longer (not that it's likely to matter), and generates more memory churn (also not likely to matter). – T.J. Crowder Dec 20 '21 at 13:57

1 Answers1

0

It is called currying

The passed created function will in your case add 10 to x and subtract 5 from y from each of the polylines in the array

If you call it with

move({ x: 5, y: -15 }); it will offset each line by 5,-15

const parse = (point) => {
  return typeof point === "object" ? point : JSON.parse(point); // did we get an object or a string? if the latter parse it
};

// move takes an offset and returns a function that uses that offset (closure)
const move = (offset) => (point) =>{
  point.x += offset.x; 
  point.y += offset.y;
  return point
};
    
// an array of objects or valid JSON strings    
const polyline = [
  { x: 0, y: 0 },
  { x: 10, y: 10 },
  '{ "x": 20, "y": 20 }', // this will be parsed
  { x: 30, y: 30 },
];
    
    
const offset = move({ x: 10, y: -5 }); // offset is returning a function to be used in the map
const path = polyline.map(parse).map(offset); // call the function for each parsed entry in the polyline
console.log({ path });
mplungjan
  • 169,008
  • 28
  • 173
  • 236