Home > Software engineering >  How to "un-flatten" array or create an array of pairs
How to "un-flatten" array or create an array of pairs

Time:11-22

I need to group the points of a <polyline> into an array of [x, y] coordinates. Usually SVGPolylineElement items validate with both comma separated values AND space only separated values.

var points = "0 0 50 0 25 50 0 0".split(/\s|,/); // or points="0,0 50,0 25,50 0,0"

// how to group the points like this
points = [[0,0], [50,0], [25,50], [0,0]];

I'm working around:

points = [].concat(points.slice().map((v,i) => {
 // what to do here?
 // I know I need to make use of i%2 === 0
 // I don't know how to break the original array
}))

I need an ES6 solution to group arrays like shown above.

CodePudding user response:

You could likely achieve the grouping by using reduce

// I have omitted parsing these values--I assume that
// it's out of scope for this question
const parsedPoints = [0, 0, 50, 20]

const res = parsedPoints.reduce((coordinates, point, index, array) => {
  if (index % 2 === 0) {
    return [...coordinates, array.slice(index, index   2)]
  }

  return coordinates
}, [])

console.log(res)
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

I'm not sure whether you also had difficulties parsing the string into an array of values? I interpreted that the question was about grouping in particular.

CodePudding user response:

If the string contains commas then it’s as simple as:

const pairs = points.split(" ").map((pairRaw) => pairRaw.split(",").map(Number));

If not, then it’s a bit harder, — you’ll have to use classic for loop:

const pairs = [];
const numbers = points.split(" ").map(Number);

for (let i = 0; i < numbers.length; i  = 2)
  pairs.push([ numbers[i], numbers[i   1] ]);

CodePudding user response:

const str = "0 0 50 0 25 50 0 0".split(/\s|,/).map(Number)
const res = []

let curr = 0
while(curr < str.length) {
    res.push([str[curr], str[curr   1]])
    curr  = 2
}

console.log(res)
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

This is one way to achieve what you're after:

// Parse the list of strings (extends your code snippet)
let points = "0 0 50 0 25 50 0 0".split(/\s|,/).map(Number);

// Loop and combine
let pointsParsed = []
for (let i=0; i<points.length; i =2){
  pointsParsed.push([points[i], points[i 1]])
}

Assuming that you're splitting with that method as the delimiter you receive between the numbers could be ',' or ' '

You could condense the LoC down more at the cost of readability on this one

CodePudding user response:

const points = '0 0 50 0 25 50 0 0';
const points2 = '0,0 50,0 25,50 0,0';

function coords(points) {

  // Find matches of a set of two numbers
  // separated by a space
  const regex = /(\d [, ]\d )/g;

  // Apply the regex to the string to get an
  // array of groups in the style "0 0"
  const match = points.match(regex);

  // Finally map over the array and take
  // each element and split it on the space or
  // the comma and then map over that array
  // to create some integers
  return match.map(el => {
    return el.split(/[ ,]/).map(Number);
  });

}

console.log(coords(points));
console.log(coords(points2));
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related