С этим форматом вы очень близки к конвертации в объект. Это не правильный JSON, но достаточно просто, если мы попытаемся решить проблему:
- Отделите объекты, чтобы из
"{id:1,another:thing},{id:2,another:item}"
мы могли получить массив, в котором каждый элемент является «объектом» и содержит только то, какими будут значения ключа -> поэтому каждый элемент равен «{id: 1, another: thing} «
- Затем каждая «строка объекта» фактически разделяется на строку для ключей и значений
{id:1,another:thing}
-> "id:1"
и "another:thing"
- Значение ключа строки можно разбить на значение ключа пары :
"id:1"
-> "id"
и "1"
.
Итак, это даст вам план со строительными блоками для каждого объекта и их ключами и значениями. Вот как это может работать как
let input = "{id:1,another:thing},{id:2,another:item}";
//capture objects like "{id:1,another:thing}"
const regexForObjects = /\{[^}]*\}/g;
let objectBlueprint = input
.match(regexForObjects) //split off each "object" as a string
.map(objString => objString.slice(1, -1)) //remove the first { and the last }
.map(item => item.split(/\s*,\s*/)) // split each string representation of an object into strings for each key and value
.map(item => item.map(subitem => subitem.split(/\s*:\s*/))) //split each key-value pair into a separate array.
console.log(objectBlueprint)
Это многословно - реализация может быть осуществлена другими способами, но это дает представление о том, что происходит, следуя шагам.
как только это будет сделано, все, что осталось, это построить объекты из этого. Каждый объект представлен массивом, который содержит массивы пар ключ-значение, поэтому мы можем очень просто реализовать функцию, взять ее и вернуть объект:
let input = [ ["id", "1"], ["another", "thing"] ];
let output = fromArrayToObject(input);
console.log(output)
function fromArrayToObject(keyValuePairs) {
return keyValuePairs.reduce((obj, [key, value]) => {
obj[key] = value;
return obj;
}, {})
}
Прямо сейчас, это только производит строки как значения. Трудно догадаться, является ли "1"
строкой или числом. Это работает как минимальная реализация, но вы также можете попытаться угадать тип значения:
let number = guessType("1");
let boolean = guessType("true");
let nul = guessType("null");
let string1 = guessType("The quick brown fox");
let string2 = guessType("something");
console.log("should be number:", typeof number);
console.log("should be boolean:", typeof boolean);
console.log("should be null:", nul === null); //typeof null -> "object", so doing an equality check
console.log("should be string:", typeof string1);
console.log("should be string:", typeof string2);
function guessType(value) {
try {
return JSON.parse(value)
} catch (e) {
return value;
}
}
Это упрощенно, но может работать во многих ситуациях. Если строка может быть проанализирована в примитиве, то это тот примитив. Если этого не может быть, тогда он рассматривается как обычная строка.
Собрав все воедино, вот как это может выглядеть:
let input = "{id:1,another:thing},{id:2,another:item}";
//convert into the structure to build into objects
let objectBlueprint = input
.match(/\{[^}]*\}/g)
.map(objString => objString.slice(1, -1))
.map(item => item.split(/\s*,\s*/))
.map(item => item.map(subitem => subitem.split(/\s*:\s*/)));
//convert each object
let output = objectBlueprint.map(fromArrayToObject)
console.log(output);
function fromArrayToObject(keyValuePairs) {
return keyValuePairs.reduce((obj, [key, value]) => {
obj[key] = guessType(value);
return obj;
}, {})
}
function guessType(value) {
try {
return JSON.parse(value)
} catch (e) {
return value;
}
}