У меня есть требование изменить JSON на JSON, имеющий значения в формате запроса SQL. Чтобы лучше объяснить.
{
"Assets": {
"ASSOCIATES_NAME": ["David", "Philip"],
"CAR_NAME": ["Verron"]
}
, "Product":{"SELLER_NAME": ["XXXXX"]}
}
Результат должен иметь значения json в виде запроса sql, оставляя ключи как есть. Таким образом, результирующий запрос будет таким:
{
Assets: "(ASSOCIATES_NAME = 'David' OR ASSOCIATES_NAME = 'Philip') AND CAR_NAME = 'Verron'",
Product: "SELLER_NAME = 'XXXXX'"
}
Я пробовал что-то, но я не мог понять это хорошо. Ниже это:
console.info(Object.entries(a).map(x => {return {
[x[0]]: `${Object.keys(x[1])} = '${Object.values(x[1])}'`,
}}))
Однако мне все еще нужно выяснить, как сгруппировать отдельные значения массива. Любое элегантное решение на основе ES6 для этого? Пожалуйста, люди, помогите мне в этом. ТИА
Да, я разобрал строку. однако проблема заключается в значениях... Я пробовал множество способов, таких как Object.entries, значения и т. д.
Пожалуйста, поделитесь этими предыдущими попытками. Лучше всего сделать простой минимально воспроизводимый пример каждой попытки.
Просто предупреждение: будьте очень осторожны с атаками SQL Injection при обработке необработанных SQL-запросов во внешнем интерфейсе.
@evolutionxbox поделился. пожалуйста, взгляните
Вот один из способов сделать это, используя Array.reduce для перебора свойств внешнего объекта и Array.map для внутренних свойств объекта для генерации выражений OR
и AND
:
const json = `{
"Assets": {
"ASSOCIATES_NAME": ["David", "Philip"],
"CAR_NAME": ["Verron"]
}
, "Product":{"SELLER_NAME": ["XXXXX"]}
}`
const params = JSON.parse(json);
const whereItems = Object.entries(params)
.reduce((c, [k, v]) => {
c[k] = Object.entries(v)
.map(([param, value]) => '(' + value.map(v => param + " = '" + v + "'").join(' OR ') + ')')
.join(' AND ');
return c;
}, {});
console.info(whereItems);
Обратите внимание, что это создает ненужные ()
вокруг одиночных сравнений (например, (SELLER_NAME = 'XXXXX')
), если вы действительно хотите избавиться от них, просто обусловите добавление этих символов value.length > 1
.
(Вы можете использовать строку шаблона, чтобы избежать обратной косой черты?)
@evolutionxbox действительно. это намного чище; Я отредактировал его. спасибо.
О боже мой. Большое спасибо @Ник. Вы спасли мой день. Только что внес небольшое изменение, предложенное @evolutionxbox ${value.map(v => param + " = '" + v + "'").join(" OR ")}
Да .... @Nick, что ты думаешь, когда значение не массив, а просто строка, если в случае одного значения. как ["Веррон"] будет просто "Веррон"
Вам нужно будет отредактировать код, который имеет дело с value
, чтобы проверить, была ли это строка или массив, возможно, проще всего просто превратить его в массив, если это не так.
проголосуйте за ответ @nik, вот еще один способ для начинающих.
f3 = function(key, arr){
var result = arr.map(function(e) {
return(`${key}='${e}'`)
})
if (result.length > 1)
return(`(${result.join(' AND ')})`)
else
return(result)
}
f2 = function(json) {
var result = []
for(const key in json) {
result.push(f3(key, json[key]))
}
return(result.join(' OR '))
}
f = function(json) {
var result = {}
for(const key in json) {
result[key] = f2(json[key])
}
return(result)
}
вызовите f над своим json
Рассмотреть строку JSON?
JSON.parse
. Кроме того, я не уверен, зачем вам нужно регулярное выражение в этой ситуации.