“Bind” values in array in JavaScript

38
October 22, 2019, at 10:50 PM

So, I have this array.

['declare', 'var', 'foo' '=', '"hello', 'world!"']

As you can see, this array is this sentence structure split by spaces: declare var foo = "hello world!"

My question is, how can I 'bind' both the "hello and world!" together, ONLY when the first begins with an " and the last ends with "? End result must be the following:

['declare', 'var', 'foo', '=', '"hello world!"']

To clarify, there could also be other things in between, and I want to include them into the final result as well.

['declare', 'var', 'foo', '=', '"hello', 'there,', 'human."']

Result must be:

['declare', 'var', 'foo', '=', '"hello there, human."']
Answer 1

Here's an approach using reduce() and keeping track of the double quotes. See the comments in the code for what is happening.

var test1 = ['declare', 'var', 'foo', '=', '"hello', 'world!"']; 
var test2 = ['declare', 'var', 'foo', '=', '"hello', 'there,', 'human."']; 
 
function glueQuotedStrings(arrayIn) { 
  var inQuotes = false; 
  var textBuffer = ''; 
  var result = arrayIn.reduce(function(i, v) { 
    if (v.charAt(0) === '"') { 
      // begin quoted string 
      inQuotes = true; 
      textBuffer += v;  
    } else if(v.substr(-1) === '"') { 
      // end quoted string 
      inQuotes = false; 
      i.push(textBuffer + ' ' + v); 
      textBuffer = ''; 
    } else if (inQuotes) { 
      // inside quoted string 
      textBuffer += ' ' + v; 
    } else { 
      // ordinary item 
      i.push(v); 
    } 
     
    return i; 
  }, []); 
   
  return result; 
} 
 
console.log(glueQuotedStrings(test1)); 
console.log(glueQuotedStrings(test2));

Answer 2

Using regex can solve this issue.

let array = ['declare', 'var', 'foo', '=', '"hello', 'there,', 'human."']; 
 
let newArray = replaceAll(array.join(), ',', ' '); 
 
let splitted = newArray.split(/ (?=(?:[^"]*"[^"]*")*[^"]*$)|"/).filter(function(item) { return item !== '' }); 
 
function replaceAll(string, term, replacement) { 
  return string.replace( 
    new RegExp(term.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), 
    replacement 
  ); 
}; 
 
console.log(splitted);

Answer 3

let arr = ['declare', 'var', 'foo', '=', '"hello', 'there,', 'human."']; 
let resultArr = []; 
let concatString = ''; 
for (let el of arr) { 
  if (el.startsWith('"')) { 
    concatString += el + ' '; 
  } 
  else if (concatString.length) { 
    if (el.endsWith('"')) { 
      concatString += el; 
      resultArr.push(concatString); 
      concatString = ''; 
    } 
    else { 
      concatString += el + ' '; 
    } 
  } 
  else { 
    resultArr.push(el); 
  } 
} 
 
console.log(resultArr);

Answer 4

The safest way to tackle this problem is to keep track of the quotes and do the String#split part yourself.

var text = 'declare var foo = "hello world!"'; 
var quotes = undefined; 
var result = [].reduce.call(text, function(result, char) { 
  if (/\s/.test(char) && !quotes) return result.push(""), result; // start new string and skip iteration 
  if (quotes === char) quotes = undefined; // exit quotes 
  else if (!quotes && /'|"|`/.test(char)) quotes = char; // enter quotes 
  result[result.length - 1] += char; // add character to string 
  return result; 
}, [""]); 
console.log(result);

READ ALSO
Mongoose ValidationError (Path is required)

Mongoose ValidationError (Path is required)

i am trying to write a post method in express

41
MongoDB Document Migrations

MongoDB Document Migrations

We currently version our document "schemas" using a __schemaVersion stored against a given document eg:

56
One package.json for a client + server React project?

One package.json for a client + server React project?

Right now, I have a project structure that looks like this:

30
Use of factory pattern in java

Use of factory pattern in java

is it a valid use of the factory pattern to "convert" objects from a given string? Example: If I have a text file where the data presents values for my object for example a numeric string "00101292877882" and I want it to create an object which will recieve...

40