Home > OS >  Splitting string into array based on first and last
Splitting string into array based on first and last

Time:06-10

I have this array :-

var a = [' DL1,C1,C5,C6','M4,DL3-7,B1-5']

And I want to split them like

[DL1,C1,C5,C6,M4,DL3,DL4,DL5,DL6,DL7,B1,B2,B3,B4,B5]

So that DL3-7 or DL3-DL7 this Split like this DL3,DL4,DL5,DL6,DL7

Reason why I am doing this, is because I want to block duplicate entry like DL3 should not come anywhere else, I am trying for loops to do this, just want to know if there is any simpler way to do it, and check for duplicacy afterwards.

Thanks

CodePudding user response:

You have to break down your problems into three parts:

  1. getting comma delimited values into different array items
  2. resolving "DL3-7" to "DL3", "DL4"...
  3. removing duplicates

Once you break down the problem, it is much easier to handle them one by one. The code is pretty readable, let me know if there is anything difficult to understand what's going on.

const a = ['DL1,C1,C5,C6', 'M4,DL3-7,B1-5']

//this will split all comma delimited values
const commaDelimit = a.map(item => item.split(',')).flat();
console.log("Separate values by comma: ")
console.log(commaDelimit);

//this will turn the ranges into individual items
//this does not account for if the number is bigger than 9. 
//you can try doing this part yourself if you need to, should be a good learning exercise.
const resolveRange = commaDelimit.map(item => {
  if (item.includes('-')) {
    const pos = item.indexOf('-');
    const beginning = Number(item.charAt(pos - 1));
    const end = Number(item.charAt(pos   1))   1;

    const toReturn = [];
    const prependString = item.substring(0, pos - 1);

    for (let i = beginning; i < end; i  ) {
      toReturn.push(`${prependString}${i}`)
    }

    return toReturn;
  }

  return item;
}).flat();

console.log("Change 'DL3-7' to DL3, DL4 and so on: ")
console.log(resolveRange);

//this will get rid of duplicates
const uniques = [...new Set(resolveRange)];
console.log("Remove duplicates: ")
console.log(uniques);

CodePudding user response:

Create an Array with that length, iterate and transform, I've just wrote the most challenged part:

function splitRange(range) {
  let a = range.split('-');
  const baseString = (a[0].match(/[a-z A-Z]/g))?.join('');
  const baseNumber =  ((a[0].match(/\d /))?.shift());
  return Array.from({length:  a.pop() - baseNumber   1}).map((_,i)=>`${baseString}${i baseNumber}`);
}
console.log(splitRange('ZC12-100'));

CodePudding user response:

Basically, @cSharp has explained the concept of data transformation to the desired output.

  1. Split by comma.

  2. Work with regex to transform the range value and append it to the array. Regex pattern & test data

  3. Distinct the array value.

var a = [' DL1,C1,C5,C6','M4,DL3-7,B1-5'];

var formatteds = a.reduce((previous, current) => {
    var splits = current.trim().split(',');

    var rangedSplits = splits.reduce((prev, cur) => {
        var pattern = new RegExp(/([A-Z]*)(\d)-[A-Z]*(\d)/);
        var match = pattern.exec(cur);

        if (match) {
            // Pattern 1: ['DL3-7', 'DL', '3', '7']
            // Pattern 2: ['DL3-DL7', 'DL', '3', '7']

            var startIndex = parseInt(match[2].toString());
            var endIndex = parseInt(match[3].toString());
            var arr = [];

            for (let i = startIndex; i <= endIndex; i  ) {
                arr.push(match[1].toString()   i);
            }

            prev = prev.concat(arr);
        } else {  
            prev = prev.concat([cur]);
        }
        

        return prev;
    }, []);

    previous = previous.concat(rangedSplits);

    return previous;
}, []);

var result = formatteds.filter((x, i, array) => array.indexOf(x) === i);

console.log(result);

  • Related