0

I have a function that returns to me [ '3000', '3001', '3002', '3003', '3004', '3005' ], where the elements within the array are generated from a range. So if I parse a line and find 3000-3005, I need to create each value in between that and return all of these values to be in a format of ports: [ item, item, item, ...].

I have tried mapping over the individual values and returning them one by one, but obviously that only returns one value, is there a way to return everything individually? I've seen questions like Return multiple values in JavaScript?, but I need the returns to be dynamic since I won't know ahead of time the length, and I feel like I'm missing something.

edit: the structure of the code on a high-level is like this

return (
...
ports: functionCall(portArr)
...
)

functionCall(portArr) {

return (portArr.map((p) => {
    if (typeof p === "string") {
      const val = parsePorts(p);

      return val;
    }

    return `${p.target}:${p.published}`;
  });

}

Where the parsePorts function is where I determine what type of port structure it is and how to handle it and thats where the function below may be called.

function createRange(port: string, range: string) {
  const ports = [];

  for (let i = parseInt(port, 10); i <= parseInt(range, 10); i++) {
    ports.push(`${i}`);
  }
  return ports;
}

So val is potentially the array of my generated port ranges and from this function is where I need to return each value individually unpacked from the array

Kevin Carlos
  • 31
  • 3
  • 9

1 Answers1

0

Below is one way to achieve this using a few array methods like .split() and .splice(). Without seeing your code I'm not sure if this will work in your broader program. For instance, is port: [] a key in some object and its value should be the returned array?

const sampleLine = '3000-3005';
const baseArray = sampleLine.split('-');
console.log(baseArray); // Returns an array with the two values provided in sampleLine.

const midArray = []; // Setting up the array where we dynamically push the values that fall between the initial two values.

// Here I'm saying that we are going to start by pushing a value that's 1 greater than the minimum in our array and go until we reach the maximum.  We push every value between the two.
for (let x = parseInt(baseArray[0]) + 1; x < baseArray[1]; x++) {
  midArray.push(x.toString());
};

baseArray.splice(1, 0, ...midArray); // Use splice and spread operator to inject the values of the midArray into the baseArray.
console.log(baseArray); // Shows an array with values 3000 to 3005.

EDIT: Updated to take into account OP's clarification in the comments section below.

// Here is our portArr with three different port formats.
const portArr = ['3000-3005', '3000:3006', '127.0.0.1:3000:3001']

// This function will be called in our createRange function.  Its job is to return a new array without non-numeric characters and other unnecessary numbers.  This establishes the "min" and "max" for our range.
const functionCall = (arr) => {
  return arr.map((port) => {
    return port.substring(port.length - 9, port.length).split(/[^0-9]/);
  });
};

// createRange takes an array and is called on our object that contains the "port" key.  We will pass in our portArr and start by calling functionCall.  We'll then iterate through each value in the multidimensional array.  Each value is an array of its own, so we use a for loop inside our forEach() method to create our range, pushing that to an interim array called stagingArr, then pushing that to the final returned array called portRangeArr.
const createRange = (arr) => {
  const formattedPortArr = functionCall(arr);
  const portRangeArr = new Array;

  formattedPortArr.forEach((portArr) => {
    let stagingArr = new Array;

    for (let x = parseInt(portArr[0]); x <= portArr[1]; x++) {
      stagingArr.push(x.toString());
    };

    portRangeArr.push(stagingArr);
  });

  return portRangeArr;
};

// Create an object with a key "port" and a value equal to the return value of calling createRange with our portArr.
const portObject = {
  ports: createRange(portArr)
};

console.log(portObject); // Should show an object with a multidimensional array where each child array contains the range of ports.
paoiherpoais
  • 334
  • 1
  • 10
  • I've edited my post to include code, sorry about that – Kevin Carlos Nov 07 '19 at 00:39
  • Okay. 1) Where's the parsePorts() code, I don't see it? 2) It looks like functionCall() is already being fed an array ("portArr"), so where are things going wrong? Are you just trying to take that array and return it as a value on an object with the key "ports"? 3) I'm not sure I understand what the desired outcome is and where your code isn't working. – paoiherpoais Nov 07 '19 at 01:21
  • parsePorts is just determining what kind of port it is, e.g. ```3000:3000, 3000-3005, 127.0.0.1:3000:3001``` and determining from there what to do with them. So in the instance of a port range such as 3000-3005, I need to generate each port in that range, 3000, 3001, 3002, 3003, 3004, 3005 to be able to expose each individual one. so ```const val = parsePorts(p);``` the return value might be an array containing each port listed above. The desired outcome is after ```const val = parsePorts(p)``` to return **each** individual element to the parent function. – Kevin Carlos Nov 07 '19 at 03:30
  • Okay I'm still a little confused at the flow of everything, but just updated my answer so let me know if that's what you're looking for. – paoiherpoais Nov 07 '19 at 04:09