javascript – Converting multidimensional array / object to x-www-form-urlencoded format

Question:

Necessary

Convert an array of the form:

[
    {
        a: 1,
        b: [1, 2, 3]
    },
    [
        {
            c: 4,
            d: 5,
            e: [
                6,
                {
                    f:7
                }
            ]
        }
    ],
    8
];

into an object of the form:

{
    "name[0][a]": 1,

    "name[0][b][0]": 1,
    "name[0][b][1]": 2,
    "name[0][b][2]": 3,

    "name[1][0][c]": 4,
    "name[1][0][d]": 5,

    "name[1][0][e][0][0]": 6,
    "name[1][0][e][0][1][f]": 7,

    "name[2]": 8,
}

name purely for beauty, and can be used as one of the input arguments for a parser function.

What have tried

  • Google;
  • Solve recursively (commented out all the lines, because it's scary):
 let processObj = (item, key) => { // наша функция-парсер if (item.constructor && item.constructor.name === "Array") { // если массив item.forEach((item0, key0) => { //перебираем как массив processObj(item0, key0); // обратно вызываем processObj, чтобы "докопться" до обычного значения типа строки или числа }); } else if (item.constructor && item.constructor.name === "Object") { // если объект for (let key0 in item) { //перебираем как объект processObj(item[key0], key0); // обратно вызываем processObj, чтобы "докопться" до обычного значения типа строки или числа } } else { // проверки выше не прошли, а значит это число или строка (скорей всего) console.log("key", key, "item", item); // просто смотрим, что к нам пришло в аргументах return { [`[${key}]`]: item }; // вот тут и начинаются проблемы. Что сюда нужно писать? } } let arr = [{"a":1,"b":[1,2,3]},[{"c":4,"d":5,"e":[6,{"f":7}]}],8]; // наш массив 'до' processObj(arr); // должно вернуть желаемый объект

And this code looks logical and successfully traverses all elements and sub-elements, reaching the final key and value (execute, for clarity).

Questions

  • How can I force this code to postpone the "path" to found numbers or strings to get the desired kind of object?
  • Am I reinventing the wheel? Is there anything in the js arsenal ready to parse arrays for request with data like x-www-form-urlencoded ?

PS: option with JSON.parse() not interesting

Answer:

let arr = [{"a":1,"b":[1,2,3]},[{"c":4,"d":5,"e":[6,{"f":7}]}],8];

const getType = q => Object.prototype.toString.call(q)

let res = foo(arr)
document.body.innerHTML += `<hr>\n${JSON.stringify(res)} `

function foo(list, props) {
    let { _path = "", res = {} } = props || {}
    for (let key in list) {
        let path = `${_path}['${key}']`
        let val = list[key]
        let typeVal = getType(val)
        if (("[object Array]" === typeVal) || ("[object Object]" === typeVal)) {
            foo(val, { _path: path, res })
        } else {
            let originVal = eval(`arr${path}`)
            let isEq = val === originVal
            document.body.innerHTML += `${JSON.stringify({ path, val, isEq, originVal })} <br>\n`
            res[path] = val
        }
    }
    return res
}
Scroll to Top