Skip to content

Instantly share code, notes, and snippets.

@nikoloza
Created October 11, 2016 08:10
Show Gist options
  • Save nikoloza/9083538fa52379173bccce660b8aebbe to your computer and use it in GitHub Desktop.
Save nikoloza/9083538fa52379173bccce660b8aebbe to your computer and use it in GitHub Desktop.
Verify parentheses

Parentheses verify function

Function verifies whether string has wrong order of parentheses or not. I made two ways of solving this, normal using for loop, and functional using filter and reduce.

It also includes unit tests for both functions and you can see it online here: for-loop and functional. Here are performance tests comparing their speed.

The code syntax is based on ES6 and Standard.

'use strict'
// test cases
isEqual(verify('---(++++)----'), 1)
isEqual(verify(''), 1)
isEqual(verify('before ( middle []) after'), 1)
isEqual(verify(') ('), 0)
isEqual(verify('} {'), 1)
isEqual(verify('<( >)'), 0)
isEqual(verify('( [ <> () ] <> )'), 1)
isEqual(verify(' ( [)'), 0)
/**
* Helper function to test if verify() works correctly.
* @param {*} expression - string to test
* @param {*} expected - expected result
*/
function isEqual (expression, expected) {
var isEqual = (expression === expected)
var msg = `${expression} is ${isEqual ? '' : 'not '}equal to ${expected}`
console[isEqual ? 'log' : 'error'](msg)
return isEqual
}
'use strict'
/**
* Function verifies whether string has wrong
* order of parentheses or not.
* @param {string} str - String to verify
* @param {string} [symbols = '<>()[]'] - Symbols to check
* @returns {number} 0 if invalid and 1 if valid
*/
function verify (str, symbols = '<>()[]') {
return str
.split('')
.filter((s) => symbols.indexOf(s) > -1)
.reduce((remainder, current, i, arr) => {
let previous = remainder.slice(-1)
let previousIndex = symbols.indexOf(previous)
let currentIndex = symbols.indexOf(current)
let isOpening = !(previousIndex % 2)
let hasClosing = previousIndex + 1 === currentIndex
if (isOpening && hasClosing)
return remainder.slice(0, remainder.length - 1)
else return remainder + current
}, '')
.length ? 0 : 1
}
'use strict'
/**
* Function verifies whether string has wrong
* order of parentheses or not.
* @param {string} str - String to verify
* @param {string} [symbols = '<>()[]'] - Symbols to check
* @returns {number} 0 if invalid and 1 if valid
*/
function verify (str, symbols = '<>()[]', recursive) {
if (!recursive) str = filter(str)
for (let i = 0; i < str.length - 1; i++) {
let currentLetter = symbols.indexOf(str[i])
let nextLetter = symbols.indexOf(str[i + 1])
let isOpening = !(currentLetter % 2)
let hasClosing = currentLetter + 1 === nextLetter
if (isOpening && hasClosing) {
str = str.slice(0, i) + str.slice(i + 2, str.length)
return verify(str, void 0, true)
}
}
return str.length ? 0 : 1
}
/**
* Function filter clears string from unnessary chars
* and leaves only desired symbols.
* @param {string} str - String to clear
* @returns {string} New clean string
*/
function filter (str) {
var regex = /[\[\]\(\)<>]/g
var match = str.match(regex)
return match ? match.join('') : ''
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment