-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
第 152 题:实现一个 normalize 函数,能将输入的特定的字符串转化为特定的结构化数据 #331
Comments
let normalize = str => {
let result = {}
let c
// 字符串转化为数组
let arr = str.split(/[\[\]]/g).filter(Boolean)
// 生成结构化数据
arr.forEach((item, index) => {
if(index != 0) {
c.children = {}
c.children.value = item
c= c.children
} else {
result.value = item
c= result
}
})
return result
}
let str = '[abc[bcd[def]]]'
normalize(str)
// {value: 'abc', children: {value: 'bcd', children: {value: 'def'}}} |
const normalize = (str) => {
var result = {}
str.split(/[\[\]]/g).filter(Boolean).reduce((obj, item, index, a) => {
obj.value = item
if(index !== a.length -1) {
return (obj.children = {})
}
}, result)
return result
} |
function normalize(str) {
let arr = str.match(/\w+/g)
let temp = {}
let obj
while(arr.length) {
let item = arr.pop()
temp.value = item
obj && (temp.children = obj)
if(arr.length) {
obj = {...temp}
temp = {}
}else {
obj = temp
}
}
return obj
} |
const normalize = str => {
const arr = str.split(/[\[\]]/).filter(Boolean);
const createArr = arr => {
return arr.reduce((obj, val, n, arr) => {
arr.length > 1 ? (obj.children = createArr(arr.slice(1))) : "";
obj.value = arr[0];
return obj;
}, {});
};
return createArr(arr);
}; |
var normalize = (str) => {
var list = str.match(/\w+/g)
var obj = {}
var curr = obj
while (key = list.shift()) {
curr.value = key
if (list.length === 0) break
curr.children = {}
curr = curr.children
}
return obj
} |
字符串仅由小写字母和 [] 组成,且字符串不会包含多余的空格。 |
let normalize = (str) => {
let arr = str.split(/[\[\]]/).filter(Boolean);
let i = 0, obj = {}, cur = obj;
while(i < arr.length) {
if (i > 0) cur = cur.children = {};
cur.value = arr[i];
i ++;
}
return obj;
} |
function normalize(str, res = {}) {
if (str) {
if (str[0] === "[") {
const exec = /^\[(\w+)(\[.*\]){0,1}\]$/.exec(str);
if (exec) {
const [, value, next] = exec;
res.value = value;
next && normalize(next, (res.children = {}));
}
} else if (!/(\[|\])/.test(str)) {
res.value = str;
}
}
return res;
}
// 测试用例
[
"[a[b[c]]]",
"",
"asd",
"[aads",
"asdasd]",
"[asddd]",
"[a[d]",
"[s[]]"
].reduce((acc, c) => ((acc[c] = normalize(c)), acc), {}); es5、纯算法: function normalize(str) {
if (!/(\[|\])/.test(str)) {
return { value: str };
}
var len = str.length,
quene = [],
res = {},
ret = res,
current = "";
for (var i = 0; i < len; i++) {
var c = str[i];
if (c === "[" || c === "]") {
if (current) {
quene.push(current);
current = "";
}
if (c === "]") {
var top = quene.shift();
if (top) {
res.value = top;
if (quene.length) {
res = res.children || (res.children = {});
}
}
}
} else {
current += c;
}
}
return ret;
} |
|
function normalize(str) {
let current, result;
while (current = str.match(/\[([a-z]+)\]/)) {
let [res, value] = current;
result = result ? { value, children: result } : { value };
str = str.replace(res, '');
}
if (!result) result = {value: str};
return result;
} |
|
|
function normalize(s) {
let arr = s.match(/\w+/g)
let result
while(arr.length) {
let cur = arr.pop()
let temp = {value: cur}
if(result) {
temp.children = result
}
result = temp
}
return result
}
// 测试
var s = 'abc'
normalize(s) // {value: "abc"}
s = '[abc[bcd[def]]]'
normalize(s)
// {value: 'abc', children: {value: 'bcd', children: {value: 'def'}}} 更过编程算法题可见 JavaScript-Algorithms |
return (obj.children = {}) 这个啥意思 呀 还是看不懂 为啥 |
简化一下代码,你可以这么理解: const normalize = (str) => {
var result = {};
str
.split(/[\[\]]/g)
.filter(Boolean)
.reduce((obj, item) => {
obj.value = item;
let children = {};
obj.children = children;
return children;
}, result);
return result;
}; |
代码写的6,顶一个,但是用这种极简的骚操作写法是为了减少代码量么,可读性不考虑么😅 |
你用了递归,你的reduce没有任何意义, 但是我没有证据 |
const normalize = function(str) {
let res = {}
str.split(/[\[\]]/).filter(Boolean).reduce((prev, curr, index) => {
if (index) prev = prev['children'] = {}
prev['value'] = curr;
return prev
}, res)
return res
} |
const normalize = (str = '') =>
str
.split(/[\[\]]/g)
.filter(Boolean)
.reverse()
.reduce((acc, cur, index) => (!index ? { value: cur } : { value: cur, children: acc }), {});
let str1 = '[abc[bcd[def]]]',
str2 = 'abc';
console.log(normalize(str1));
console.log(normalize(str2)); |
正则真香
|
都在正则,来个不用正则的: /**
* 第 152 题:实现一个 normalize 函数,能将输入的特定的字符串转化为特定的结构化数据
* 字符串仅由小写字母和 [] 组成,且字符串不会包含多余的空格。
* 示例一: 'abc' --> {value: 'abc'}
* 示例二:'[abc[bcd[def]]]' --> {value: 'abc', children: {value: 'bcd', children: {value: 'def'}}}
*
* @version 2020-8-11
*/
const CHILDREN_START = Symbol();
const CHILDREN_END = Symbol();
const VALUE = Symbol();
const EOF = Symbol();
function scanner(s) {
let pos = 0;
return {
[Symbol.iterator]() {
return this;
},
next() {
let token = {
value: "",
type: EOF,
done: true,
};
for (; pos < s.length; ) {
let c = s.charAt(pos++);
switch (c) {
case "'":
continue;
case "[":
token.value = "[";
token.type = CHILDREN_START;
token.done = false;
return token;
case "]":
token.value = "]";
token.type = CHILDREN_END;
token.done = false;
return token;
default:
token.type = VALUE;
token.done = false;
token.value += c;
while (pos < s.length) {
c = s.charAt(pos++);
if (["'", "[", "]"].includes(c)) {
pos--;
break;
}
token.value += c;
}
return token;
}
}
return token;
},
};
}
function normalize(str) {
const scan = scanner(str);
let obj = {};
let temp = obj;
for (let v = scan.next(); !v.done; v = scan.next()) {
switch (v.type) {
case CHILDREN_START:
temp.children = {};
temp = temp.children;
break;
case VALUE:
temp.value = v.value;
break;
}
}
if (!obj.value) {
obj = obj.children;
}
return obj;
}
console.log(JSON.stringify(normalize("[abc[bcd[def]]]"))); // => {"value":"abc","children":{"value":"bcd","children":{"value":"def"}}}
console.log(JSON.stringify(normalize("abc"))); // => {"value":"abc"} |
/**
* 递归版本
* @param {string} str
*/
export function normalizeRecur(str) {
const matchRe = /^\[.*\]$/
const valueRe = /^\[([^\[\]]*)/
let root = {}
if (matchRe.test(str)) {
root.value = str.match(valueRe)[1]
root.children = normalize(str.slice(1 + root.value.length, str.length - 1))
} else if (str.length > 0) {
root.value = str
} else {
root = undefined
}
return root
}
/**
* 非递归版本
* @param {string} str
*/
export function normalize(str) {
const stack = []
const startRe = /^\[/
const endRe = /^\]/
const valueRe = /^\[([^\[\]]*)/
let root
let parent
while(str) {
if(startRe.test(str)) {
let valueMatch = str.match(valueRe)
let cur = {}
root = root || cur
if (parent) parent.children = cur
cur.value = valueMatch[1]
stack.push(cur)
parent = cur
str = str.slice(valueMatch[0].length)
} else if (endRe.test(str)) {
str = str.slice(1)
stack.pop()
}
}
return root
} |
function normalize(str) {
var array = str.match(/[a-z]+/g);
var obj = {};
array.reduce((acc, cur, index) => {
const isInLast = index == array.length - 1;
acc.value = cur;
if (!isInLast) {
acc.children = {}
}
return isInLast ? acc : acc.children
}, obj);
return obj;
}
normalize('abc')
normalize('[abc[bcd[def]]]') |
function normalize(str) {
let len = str.length, stack = [], j = 0
for (let i = 0; i < len; i++) {
if (str[i] === '[') {
j++
} else if (str[i] === ']') {
j--
} else {
if (!stack[j]) {
stack[j] = ''
}
stack[j] = stack[j] + str[i]
}
}
if (stack.length && stack[0] === undefined) {
stack.shift()
}
let root = {}, temp = root
for (let i = 0; i < stack.length; i++) {
temp.value = stack[i]
if (i !== stack.length - 1) {
temp.children = {}
temp = temp.children
}
}
return root
} |
|
我想说,以上考虑过这种情况么 |
function normalize(str) {
const arr = str.split(/[[\]]/).filter(Boolean) // str.split(']').join('').split('[').filter(Boolean)
return arr.length > 1
? arr.reverse().reduce((acc, cur, index) => ({
value: cur,
children: index === 1 ? { value: acc } : acc
}))
: { value: str }
} |
function parse(str){
const list = str.split(/(\[|\])/).filter(val =>val);
let result = null;
let temp = null;
for(let i = 0, len = list.length; i< len; i++){
const value = list[i];
if(value == ']'){
break;
}
switch(value){
case '[':
if(result){
result = (result.children || (result.children = {}));
}else{
result = temp = {};
}
break;
default:
if(result){
result.value = value;
}else{
result = temp = { value: value};
}
break;
}
}
return temp;
} |
function normalize(str) {
let res = str.match(/\[(.+?)\]/);
let p = res ? res[1] : str;
let arr = p.split('[');
var obj = {};
var cur = obj;
for (let i = 0; i < arr.length; i++) {
if (i > 0) {
cur.children = {value: arr[i]}
cur = cur.children
} else {
cur.value = arr[i];
}
}
return obj;
} |
function normalize(str) {
let arr = str.split(/[\[\]\s]+/).filter(Boolean);
let result = {};
arr.reduce((pre, next) => (pre.children = { value: next }), result);
return result.children;
} |
// 字符串仅由小写字母和 [] 组成,且字符串不会包含多余的空格。
// 示例一: 'abc' --> {value: 'abc'}
// 示例二:'[abc[bcd[def]]]' --> {value: 'abc', children: {value: 'bcd', children: {value: 'def'}}}
function format(str) {
const stack = []
let i = 0
let result
while (i < str.length) {
switch (str[i]) {
case "[":
i++
break;
case "]":
i++
stack.pop()
break;
default:
let val = str[i];
i++
while (!['[', ']'].includes(str[i]) && i < str.length) {
val += str[i];
i++
}
const node = { val };
if (!stack.length) {
result = node
}
if (stack.length && stack.length - 1 < stack.length) {
stack[stack.length - 1].children =
stack[stack.length - 1].children || [];
stack[stack.length - 1].children.push(node);
}
stack.push(node);
}
}
return result;
}
console.log("format", format("[abc[bcd[def]]]"));
console.log("format", format("[abc[bcd[def][1]][2]]")); |
function normalize(str) {
let obj = {};
const vals = str.split(/[\[\]]/g).filter(Boolean);
for (let i = vals.length - 1; i >= 0; i--) {
!obj.value ? obj.value = vals[i] : obj = {
value: vals[i],
children: {
...obj
}
}
}
return obj
} |
用 function normalize(input) {
const arr = input.replace(/\[|\]/g, ',').split(',').filter(itm => itm);
let result = {};
arr.reduce((obj, cur, idx) => {
const temp = {};
temp.value = cur;
if (obj.children) obj.children = temp;
if (idx !== arr.length - 1) temp.children = {};
if (idx === 0) result = temp;
return temp;
}, result);
return result;
}
console.log(normalize('abc'));
console.log(normalize('[abc[bcd[def]]]')); |
用栈实现 function normalize(str) {
const stack = [];
let res = {};
for (let c of str) {
if (c === ']') {
let value = [];
let top = stack.pop();
while (top !== '[') {
value.unshift(top);
top = stack.pop();
}
if (res.value) {
res.children = { ...res };
}
res.value = value.join('');
continue;
}
stack.push(c);
}
if (stack.length) {
res.value = stack.join('');
}
return res;
} |
es6实现 function normalize(str) {
let obj = {};
let arr = str.split(/[\[\]]/g).filter(Boolean);
arr.reduce((acc, cur) => {
while (acc.children) {
acc = acc.children;
}
acc.value = cur;
acc.children = {};
return acc;
}, obj);
return obj;
} es5实现 function findChild(obj) {
return obj.children ? findChild(obj.children) : obj;
}
function normalize2(str) {
let arr = str.split(/[\[\]]/g).filter(Boolean);
let res = {};
while ((item = arr.shift())) {
let obj = findChild(res);
obj.value = item;
obj.children = {};
}
return res;
} 上面同学的测试用例 let arr = [
"[a[b[c]]]",
"",
"asd",
"[aads",
"asdasd]",
"[asddd]",
"[a[d]",
"[s[]]",
];
arr.reduce((acc, c) => ((acc[c] = normalize(c)), acc), {}); |
reverse 倒著回來 function normalize(str) {
const arr = str.replaceAll(']', '').split('[').filter(Boolean)
const res = arr.reverse().reduce((obj, value, idx, a) => {
if (idx > 0) {
obj.children = {
...obj
}
}
obj.value = value
return obj
}, {})
return res
}
const str = '[abc[bcd[def]]]'
console.log(normalize(str)) |
function parse(str) {
let s = str
const tokens = [
/^\[/,
/^\w+/,
/^\]/
]
let res = {}
let point = undefined
let parentMap = new Map()
while (s) {
for (let i = 0, l = tokens.length; i < l; i++) {
let token = s.match(tokens[i])
if (token) {
s = s.replace(tokens[i], '')
switch (i) {
case 0:
if (!point) {
point = res
parentMap.set(point, undefined)
} else {
point.children = {}
parentMap.set(point.children, point)
point = point.children
}
break
case 1:
point.value = token[0]
break
case 2:
point = parentMap.get(point)
break
}
}
}
}
return res
} |
const normalize = (str = '') => {
const result = {};
const array = str.split(/[\[\]]/g).filter(Boolean);
const { length } = array;
array.reduce((previousValue, currentValue, currentIndex) => {
previousValue.value = currentValue;
if(currentIndex !== length - 1) return (previousValue.children = {})
}, result);
return result;
} |
/**
*
* @param {string} str
*/
const Normalize = (str) => {
const obj = Object.create(null);
const arr = str.match(/\w+/g); //[ 'abc', 'bcd', 'def' ]
let index = 0;
(function createObj(obj) {
obj.value = arr[index++];
if (index === arr.length) return;
obj.children = {};
return createObj(obj.children);
})(obj);
console.log(JSON.stringify(obj, undefined, ' '));
return obj;
};
const Normalize = (str) => {
const arr = str.match(/\w+/g); //[ 'abc', 'bcd', 'def' ]
const obj = Object.create(null);
arr.reduce((pre, current, index) => {
pre['value'] = current;
if (index == arr.length - 1) return null;
pre['children'] = {};
return pre['children'];
}, obj);
return obj;
};
console.log(Normalize('[abc[bcd[def]]]')); |
function normalize(str) {
const list = str.split(/[\[\]]/).filter(Boolean); // ['abc','bcd','def']
const res = {};
let temp = {};
for (let i = 0; i < list.length; i++) {
const item = list[i];
if (i === 0) {
res.value = item;
temp = res;
} else {
temp.children = {
value: item
};
temp = temp.children;
}
}
return res;
} |
let arr = '[abc[bcd[def[hij]]]]'.match(/\w+/g)
//['abc', 'bcd', 'def']
let obj = {};
let res = {
val: arr.pop()
};
while (arr.length > 0) {
res = {
val: arr.pop(),
child: res
};
} |
const normalize = (v) => {
if (v[0] != '[') return { value: v };
const jsonStr = v.replace(/\[([^\[\]]+)/g, (_, value) => (`"value": "${value}","children":{`))
.replaceAll(']', '}')
.replace(',"children":{}', '');
return JSON.parse(`{${jsonStr}}`);
}; |
const normalize = (str) => {
const root = {};
const holdMap = [];
let hold = root;
let floor = 0;
let subVal = '';
const setVal = () => {
if (!subVal) return;
hold.value = subVal;
subVal = '';
};
for (var c of str) {
if (c === '[') {
setVal();
holdMap[++floor] = hold;
hold.children = {};
hold = hold.children;
} else if (c === ']') {
setVal();
hold = holdMap[--floor];
} else {
subVal += c;
}
}
setVal();
return root.value ? root : (root.children || {});
}; |
|
看起来大部分题解都只能支持逐级的链式结构,以数组方式处理字符串必然会丢失数据的结构化。这样处理数据导致重要参数丢失显然是不够健壮
可以以栈的方式存储上一级对象名称并根据对象的堆特性,来实现将字符串处理为简单对象的能力。 |
function nomalize(str) {
const props = str.match(/\w+/g);
if (props.length === 1) {
return { value: props[0] };
}
return props.reduceRight((children, parent) => {
if (typeof children === 'string') {
children = { value: children };
}
return { value: parent, children };
});
}
console.log(JSON.stringify(nomalize('abc')));
console.log(JSON.stringify(nomalize('[abc[bcd[def]]]'))); |
字符串仅由小写字母和 [] 组成,且字符串不会包含多余的空格。
示例一:
'abc' --> {value: 'abc'}
示例二:
'[abc[bcd[def]]]' --> {value: 'abc', children: {value: 'bcd', children: {value: 'def'}}}
The text was updated successfully, but these errors were encountered: