#javascript #массивы
Необходимо Конвертировать массив вида: [ { a: 1, b: [1, 2, 3] }, [ { c: 4, d: 5, e: [ 6, { f:7 } ] } ], 8 ]; в объект вида: { "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 тут чисто для красоты, и может быть использован как один из аргументов на вход для функции-парсера. Что пробовал Гуглить; Решить рекурсивно (прокомментировал все строки, ибо страшно): 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); // должно вернуть желаемый объект И этот код выглядит логично и успешно проходится по всем элементам и подэлементам достигая конечного ключа и значения (выполнить, для ясности). Вопросы Как заставить этот код откладывать "путь" до найденных чисел или строк, чтобы получить желаемого вида объект? Изобретаю ли я велосипед? Есть ли в арсенале js что-нибудь готовое для парсинга массивов для запроса с данными типа x-www-form-urlencoded? PS: вариант с JSON.parse() не интересен
Ответы
Ответ 1
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 += `
\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 })}
\n` res[path] = val } } return res }Ответ 2
Разобрался сам. Комментировать каждую строчку лень поэтому, если возникнут вопросы - задавайте в комментариях - отвечу. Также буду рад кодревью или критике от более опытных js-программистов. Функция записывается в прототип массива и вызвать ее можно так: yourArray.parseForRequest([name]), где name - необязательная строка, которая будет лежать в основании имен свойств полученного объекта. Актуальность / Новизна Посредством этого кода можно отправить многомерный массив на сервер через x-www-form-urlencoded и переменная $_POST примет подмассивы (если они являются массивами) как массивы, а не как [object Object]. Т.е. подмассивы будут доступны как обычно через $_POST[a][b][c][d] - понятно. Array.prototype.parseForRequest = function(name) { let parse = (function() { let pathStore = {}; let parser = (item, key, tempPath) => { (() => { !tempPath && (tempPath = ""); if (item.constructor && item.constructor.name === "Array") { item.forEach((item0, key0) => { let currentPath = tempPath + `[${key0}]`; parser(item0, key0, currentPath); }); } else if (item.constructor && item.constructor.name === "Object") { for (let key0 in item) { let currentPath = tempPath + `[${key0}]`; parser(item[key0], key0, currentPath); } } else { pathStore[tempPath] = item; } })(); return pathStore; } return parser; })(); return parse(this, null, name); } let arr = [{"a":1,"b":[1,2,3]},[{"c":4,"d":5,"e":[6,{"f":7}]}],8]; console.log( arr.parseForRequest("name") ); // поехали
Комментариев нет:
Отправить комментарий