基於空間存儲性能和高效的考慮,我新設計了一種的新的邏輯前綴表達式前端
如圖,咱們能夠用這種前綴表達式: (|A, (&B, C, (|E, F, G)), (|D, (&H, I))) 對邏輯如上邏輯節點進行表達git
咱們將節點ID表明節點,節點ID能夠是數字或字母github
兩個概念: 條件 和 分組算法
條件必定存在於分組中數據庫
條件之間存在 且 和 或的關係markdown
例如一個簡單的分組數據結構
(&1, 2) 那麼說明 條件1 和 條件2 爲且的關係oop
(|1, 2) 那麼說明 條件1 和 條件2 爲或的關係性能
子分組 和 條件也存在邏輯關係測試
例如:(&1, 2, (|3, 4))
那麼 條件1 和 條件2 和 子分組(3, 4) 的關係爲且,有且僅當條件一、條件2和子分組的條件同時成立,該輸出項才輸出 true
測試用例1:(&10,20,30,(|4,5,6),(&7,8,9))
測試用例2:(&(|3),20,(&5,6,7))
測試用例3:(&(|A),B,(&C,D,E))
測試用例4:(|A, (&B, C, (|E, F, G)), (|D, (&H, I)))
function logicExpression2Object (str) {
try {
let at = 0
let ch = ''
let next = function () {
ch = str.charAt(at)
at += 1
while (ch && ch.trim() === '') {
next()
}
return ch
}
let group = function () {
let newGroup = {
_logic: void 0,
_values: []
}
next('(')
newGroup._logic = value()
while (ch !== ')') {
newGroup._values.push(value())
}
next(')')
return newGroup
}
let and = function () {
let r = ch
next()
return r
}
let or = function () {
let r = ch
next()
return r
}
let strings = function () {
let chars = ''
while (/\w/.test(ch)) {
chars += ch
next()
}
return chars
}
let number = function () {
/** 只考慮無符號整型數字字符 */
let chars = ''
while (/\d/.test(ch)) {
chars += ch
next()
}
return chars
}
let value = function () {
switch (ch) {
case '(':
return group()
case '&':
return and()
case '|' :
return or()
case ',':
next()
return value()
default:
if (/\d/.test(ch)) {
return number()
} else if (/\w/.test(ch)) {
return strings()
} else {
throw new Error('邏輯式不合法,解析出錯')
}
}
}
next()
return value()
} catch (e) {
console.error(e)
return void 0
}
}
logicExpression2Object('(|A, (&B, C, (|E, F, G)), (|D, (&H, I)))')
// {_logic: "|", _values: Array(3)}
// _logic: "|"
// _values: (3) ["A", {…}, {…}]
// __proto__: Object
複製代碼
function object2LogicExpression (obj) {
let result = '('
// _groupId 僅前端數據結構使用,方便進行單通道標註,不與數據庫同步
let {_logic, _values} = obj
result += _logic
for (let i = 0; i < _values.length; i++) {
let value = _values[i]
if (typeof value === 'string') {
result += value
} else {
result += this.object2LogicExpression(value)
}
if (!(i === _values.length - 1)) {
result += ','
}
}
result += ')'
return result
}
object2LogicExpression(logicExpression2Object('(|A, (&B, C, (|E, F, G)), (|D, (&H, I)))'))
// (|A,(&B,C,(|E,F,G)),(|D,(&H,I)))
複製代碼
從存儲上看,這種數據結構較JSON結構輕量很多
以(&A, B) 爲例
JSON須要{ "logic": "&", values: ["A", "B"] } 這麼多字符
可是,從可讀性和易用性的角度來看,Json 結構更符合多人協做的場景
字節跳動招人啦,歡迎牛逼的同窗加入咱們,我在互娛-影像前端等你哦~