将 params 对象序列化为 url

BT1*_*101 1 javascript algorithm loops object

我们有这样的输入

const params = {
  id: 1,
  filters: {
    price: {
      min: 101,
      max: 300
    }
  },
  sorters: {
    sortBy: 'price',
    order: 'desc'
  }
}
Run Code Online (Sandbox Code Playgroud)

我们希望输出看起来像这样id=1&min=101&max=300&sortBy=price&order=desc

对象是嵌套的。如果我们的对象只有 1 级(对象内没有对象),那么我们可以简单地这样做

for (const [key, value] of Object.entries(object1)) {
  arr.push(`${key}=${value}`);
}
Run Code Online (Sandbox Code Playgroud)

然后可能.join用 数组&。但在本例中这还不够。我的第一个想法是将这个 for 循环放入内部,如下所示:

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('&'))
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,但代码对我来说看起来很糟糕。我将其嵌套了三次,如果我有更多嵌套对象,我需要在那里放置另一个 for 循环。但每个级别的对象的模式都是相同的。我可以以某种方式重构它,这样即使我输入了 7 个嵌套对象它也能工作吗?

adi*_*iga 5

您可以使用一个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()
)
Run Code Online (Sandbox Code Playgroud)