我们有这样的输入
const params = {
id: 1,
filters: {
price: {
min: 101,
max: 300
}
},
sorters: {
sortBy: 'price',
order: 'desc'
}
}
,我们希望输出看起来像这样id=1&min=101&max=300&sortBy=price&order=desc
。
对象被嵌套。如果我们只有一个级别的对象(对象中没有对象),那么我们可以简单地做
for (const [key, value] of Object.entries(object1)) {
arr.push(`${key}=${value}`);
}
然后可能是.join
和&
的数组。但是在这种情况下,这还不够。不过,我的第一个方法是将其内部设置为这样的循环:
const paramsStringify = (paramsObject) => {
const arr = []
for (const [key, value] of Object.entries(paramsObject)) {
if(typeof value === 'object') {
for (const [key2, value2] of Object.entries(value)) {
if(typeof value2 === 'object') {
for (const [key3, value3] of Object.entries(value2)) {
console.log('3rd lvl', `${key3}: ${value3}`);
arr.push(`${key3}=${value3}`)
}
} else {
console.log('2nd lvl', `${key2}: ${value2}`);
arr.push(`${key2}=${value2}`)
}
}
} else {
console.log('1st lvl', `${key}: ${value}`);
arr.push(`${key}=${value}`)
}
}
console.log('arr', arr.join('&'))
}
this is working fine,但是代码对我来说却很糟糕。我将其嵌套了3次,如果我有更多的嵌套对象,则需要在其中放置另一个for循环。但是每个对象级别的模式都是相同的。我可以以某种方式重构它,即使我输入了7个嵌套对象也可以正常工作吗?
答案 0 :(得分:3)
const params = {
id: 1,
filters: {
price: {
min: 101,
max: 300
}
},
sorters: {
sortBy: 'price',
order: 'desc'
}
}
function add(a, o) {
for (const [key, value] of Object.entries(o)) {
if (typeof value === 'object') add(a, value); // recursion
else a.push(`${key}=${value}`); // only if value not-an-object
}
return a;
}
console.log(add([], params).join("&"))
这是一个简单的递归版本。如果要支持更复杂的结构(数组,重复键等),可能需要对其进行调整
答案 1 :(得分:3)
您可以使用URLSearchParams
对象,然后将键值对递归地附加到该对象。这将自动对值进行编码。
const params = {
id: 1,
filters: { price: { min: 101, max: 300 } },
sorters: { sortBy: "price", order: "desc" }
}
function getParam(o, searchParam = new URLSearchParams) {
Object.entries(o).forEach(([k, v]) => {
if (v !== null && typeof v === 'object')
getParam(v, searchParam)
else
searchParam.append(k, v)
})
return searchParam
}
const searchParam = getParam(params);
console.log(
searchParam.toString()
)
答案 2 :(得分:0)
假设您的对象符合您的示例,请使用URLSearchParams对象,并避免使用正则表达式进行递归
const params = {
id: 1,
filters: {
price: {
min: 101,
max: 300
}
},
sorters: {
sortBy: 'price',
order: 'desc'
}
}
const js = JSON.stringify(params);
const re = /"(\w+)":[^\{]?"?(\w+)"?/g
const usp = new URLSearchParams();
js.match(re).forEach(str => {
const [key,val] = str.split(":");
usp.set(key.replace(/"/g,""),val.replace(/"/g,""))
})
console.log(usp.toString())
答案 3 :(得分:-2)
如果您不想为每个嵌套对象编写相同的逻辑,则需要创建一个递归函数。有关递归函数的更多信息,请参见https://www.javascripttutorial.net/javascript-recursive-function/。