0

I have a use case where the user could paste something in a text area and I'd like to split them based on one of the following use cases:

Problem:

How can I make sure I can catch comma space, comma new line, newline from the string? Would a regex help here?

Context:

I could do

"1, 2, 3".split(', ') // returns [1,2,3]
"1,\n2,\n3,\n".split(',\n') // [1,2,3]
"1\n2\n3\n".split('\n') // [1,2,3]

const formatDataAndReturnArr = (inputString) => {
  return inputString.split(', ') // for comma space
}

How do I account all three cases into one? Can we sanitize the input somehow and just return the array?

halfer
  • 19,824
  • 17
  • 99
  • 186
TechnoCorner
  • 4,879
  • 10
  • 43
  • 81

4 Answers4

1

Nice exercise, you can do this with a bit of plain JavaScript. The basic idea is remove what you don't want, replace everything with a common denominator and then split it into your array.

function sanatizeToArray(str){
    
    str = str || "";
    str = str.replaceAll(" ",""); // get rid of spaces!
    str = str.replaceAll(/\n/g, ","); // change new lines into commas
    str = str.replaceAll(",,",","); // get rid of duplicates
    return str.split(","); // break it down!
}


   // test
    sanatizeToArray("1,2,3")
    (3) ["1", "2", "3"]

    sanatizeToArray("1, 2, 3")
    (3) ["1", "2", "3"]

    sanatizeToArray("1\n 2, 3")
    (3) ["1", "2", "3"]
MartinWebb
  • 1,998
  • 1
  • 13
  • 15
  • If you paste the code into JS console log, and run the tests I show, each returns a sanitized array of the results, I would need an example of a string which fails. – MartinWebb Jul 22 '21 at 19:19
  • When I run it in console it works fine, but however when I run it in the context of the React app, it gives a different output :( so confused. Hence i linked the codesandbox. I'd appreciate some help @MartinWebb – TechnoCorner Jul 22 '21 at 22:55
  • You would need to answer this issue as resolved as - as you say, the solution works. Then create another question showing your code and the issue you have, can you accept the answer? – MartinWebb Jul 23 '21 at 00:41
  • Upvoted. This solution does work if i run in V8 console but if i run in the context of React, for some reason it doesn't work. Infact this line `str = str.replaceAll("\n",",");` doesn't replace new line with commas in my case. Not sure why. – TechnoCorner Jul 23 '21 at 16:23
  • I have upgraded the answer - try again see if the newline replace with commas now works for you. – MartinWebb Jul 24 '21 at 04:14
  • I think there's a bug in the code. I don't think we are using replace all function at all since it hasn't been created on string prototype. – TechnoCorner Jul 25 '21 at 05:33
  • 1
    I have removed the replaceAll function, you are right it was not being used. Since you have replaceAll, you do not need this. However there was another error the new line replace was not using replaceAll, if you take a look I have updated the code in the answer. – MartinWebb Jul 25 '21 at 15:04
  • This is great, just one question, when i do `3,000, 4,000` (thousand comma space 2000) it doesn't seem to work. can you help with this use case? Pretty much everything else is done. Upvoted your answer. – TechnoCorner Jul 26 '21 at 17:34
  • Well it wont. The problem is how do we determine if 3,101 is 3101 or 3 and a 101. In the initial Q you asked this problem was not disclosed. You asked for it to split or commas and even using a regx how would you determine whether an entry such as 3,101 is one number or two? – MartinWebb Jul 26 '21 at 18:27
  • I think you have a design issue and without knowing the full scope of what problem you are trying to solve I can not help. I think the solution provided solves the initial issue? – MartinWebb Jul 26 '21 at 18:30
1

Personally I'd combine all valid delimiters into a single regular expression and split with it:

const split = re => str => str.split(re).filter(Boolean);
const splitDelim = split(/(?:[,\s]+)/);

console.log(splitDelim("1, 2, 3"));
console.log(splitDelim("1,\n2,\n3,\n"));
console.log(splitDelim("1\n2\n3\n"));
customcommander
  • 17,580
  • 5
  • 58
  • 84
  • thank you so much for the response. I've used your code and tried to build this, however it doesn't seem to work well for use case 2, 3: https://codesandbox.io/s/money-input-example-2-vsom5?file=/src/components/MoneyInputList.jsx Not sure what i am doing wrong. Please kindly check. I just want to make sure i'm inserting things in new line. – TechnoCorner Jul 22 '21 at 19:07
  • I think, just can trim instead of filter bolean. – xdeepakv Oct 17 '21 at 18:53
0
  • Using split, just check which of the cases returns an array:

console.log(catchCommaNewline("1, 2, 3"));
console.log(catchCommaNewline("1,\n 2,\n 3"));
console.log(catchCommaNewline("1\n 2\n 3"));

function catchCommaNewline(s) {
  // remove white spaces
  s = s.split(" ").join("");
  // check which case returns an array of min-length = 2
  if (s.split(",\n").length-1) return s.split(",\n");
  if (s.split(",").length-1) return s.split(",");
  if (s.split("\n").length-1) return s.split("\n");
  return s;
}

Case 1:

"1, 2, 3"

Array will be returned when passing through this condition:

if (s.split(",").length-1) return s.split(",");

Case 2:

"1,\n 2,\n 3"

Array will be returned when passing through this condition:

if (s.split(",\n").length-1) return s.split(",\n");

Case 3:

"1\n 2\n 3"

Array will be returned when passing through this condition:

if (s.split("\n").length-1) return s.split("\n");
AlexSp3
  • 2,201
  • 2
  • 7
  • 24
0

You can trim the string and then split it.

const formatDataAndReturnArr = (inputString) =>
  inputString.trim().split(/,?[\s\n]/);

console.log(formatDataAndReturnArr("1, 2, 3"));
console.log(formatDataAndReturnArr("1,\n2,\n3,\n"));
console.log(formatDataAndReturnArr("1\n2\n3\n"));
xdeepakv
  • 7,835
  • 2
  • 22
  • 32