Попробуйте выполнить следующий код для анализа вашего ответа php json: read.php
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script type="text/javascript">
$.ajax({
url:'index.php',
data:{},
type:"POST",
success:function(result) {
jsondecoded = $.parseJSON(result);
$.each(jsondecoded, function(index, value) {
$("#servers").text($("#servers").text() + " " + value.servername);
console.log(value.start);
console.log(value.end);
console.log(value.id);
});
},
statusCode: {
404: function() {
alert( "page not found" );
}
}
});
</script>
server.php
<?php
echo '[{"start":"2017-08-29","end":"2017-09-01","id":"22"},{"start":"2017-09-03","end":"2017-09-06","id":"23"}]';
?>
Если вы можете написать рекурсивную функцию, которая лучше всего подходит для производительности.
Но если вы хотите пропустить рекурсивный вызов с (для каждого ключа в вложенном объекте), вы можете попробовать JSON.parse
с дополнительным параметром (обратный вызов), который будет называться рекурсивно. как обобщенное решение, я добавляю фрагмент (с JSON.parse
, предполагая, что помощь в написании рекурсивной функции не должна быть принята / часть этого ответа).
Но помните, ЕСЛИ вы беспокоитесь о производительности эффективность вы не должны использовать это, поскольку вы должны стягивать (может быть большой объект) и снова анализировать. Но если у вас есть строка JSON, это должно быть одним из лучших решений.
var anyObject = [
{
"Attr": [
{
"power": { "p1": "str", "t3": "str" },
"light": [
{"test": "str"},
{"test2": [ { "t4": "str" }]}
]
}
]
},
{
"Attr1": [
{
"power1": { "p2": "str", "t5": "str" },
"light1": [
{ "test3": "str" },
{ "test_x": [
{ "t_x": "str" },
{ "t_y": [
{ "t_y1": "str" }
]
}
]
}
]
}
]
}
]
function getKeys(obj, str) {
let resultArr = [];
JSON.parse(JSON.stringify(obj), (key, val) => {
if(val === str) { resultArr.push(key) }
return val;
} )
return resultArr;
}
console.log(getKeys(anyObject, 'str'))
Это не зависит от конкретного случая, вы можете есть все ключи, если вы передадите другой обратный вызов в JSON.parse
, а также можете преобразовать объект с помощью этого (возвращаемое преобразованное значение вместо фактического значения)
И если вы хотите использовать lodash для повторного итерации объекта, то вы можете использовать _.cloneDeepWith
для рекурсивного итерации объекта.
Вот рабочий пример:
let anyObject = [
{
"Attr": [
{
"power": { "p1": "str", "t3": "str" },
"light": [
{"test": "str"},
{"test2": [ { "t4": "str" }]}
]
}
]
},
{
"Attr1": [
{
"power1": { "p2": "str", "t5": "str" },
"light1": [
{ "test3": "str" },
{ "test_x": [
{ "t_x": "str" },
{ "t_y": [
{ "t_y1": "str" }
]
}
]
}
]
}
]
}
];
function getKeys(obj, str) {
let resultArr = [];
_.cloneDeepWith(obj, (value, key) => { value === 'str' && resultArr.push(key)});
return resultArr;
}
console.log(getKeys(anyObject, 'str'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
IMHO, вы ищете что-то вроде этого:
var testArr = [{"Attr":[{"power":{"p1":"str","t3":"str"},"light":[{"test":"str"},{"test2":[{"t4":"str"}]}]}]},{"Attr1":[{"power1":{"p2":"str","t5":"str"},"light1":[{"test3":"str"},{"test_x":[{"t_x":"str"},{"t_y":[{"t_y1":"str"}]}]}]}]}];
var strFind = (arr, accumulator = []) => {
arr.forEach(obj => {
Object.entries(obj).forEach(([key, value]) => {
if (value === "str") accumulator.push(key);
if (Array.isArray(value)) strFind(value, accumulator);
if (key.includes("power")) {
Object.entries(value).forEach(([cKey, cValue]) => {
if (cValue === "str") accumulator.push(cKey);
})
}
});
})
return accumulator;
}
console.log(strFind(testArr));
Вот еще одна возможность, использующая естественно рекурсивный характер JSON.stringify
:
const input = [{"Attr":[{"power":{"p1":"str","t3":"str"},"light":[{"test":"str"},{"test2":[{"t4":"str"}]}]}]},{"Attr1":[{"power1":{"p2":"str","t5":"str"},"light1":[{"test3":"str"},{"test_x":[{"t_x":"str"},{"t_y":[{"t_y1":"str"}]}]}]}]}];
const output = [];
JSON.stringify(input, (key, val) => {
if (val === 'str') output.push(key);
return val;
});
console.log(output);
Еще одна попытка использования JSON.stringify
и синтаксического анализа строк:
const result = JSON.stringify(data)
.match(/"[^"]+":"str"/g) // get all "xxx":"str" pairs
.map(r => r.substring(1, r.indexOf(':') - 1)); // pick out all "xxx"
console.log(result);
// ["p1", "t3", "test", "t4", "p2", "t5", "test3", "t_x", "t_y1"]
.map
не нужно, используйте вместо него lookahead.
– CertainPerformance
13 July 2018 в 09:33
Попробуйте что-то вроде этого:
var array = [];
function searchForStringInJsonRecursive (jsonData, str) {
for(var i in jsonData) {
// If the element is an Array or nested object continue to search
if (typeof jsonData[i] === 'object') {
searchForStringInJsonRecursive(jsonData[i], str);
}
// If the element is not an Object and matches str add the it to the array
else if (jsonData[i] === str) {
array.push(i);
}
}
}
Предполагая, что ваш json находится в переменной с именем data
, вы можете вызвать функцию следующим образом: searchForStringInJsonRecursive(data, 'str');
array
будет содержать все ключи, которые соответствие содержимого 'str'
Вот один из способов: lodash
:
var testArr = [{"Attr":[{"power":{"p1":"str","t3":"str"},"light":[{"test":"str"},{"test2":[{"t4":"str"}]}]}]},{"Attr1":[{"power1":{"p2":"str","t5":"str"},"light1":[{"test3":"str"},{"test_x":[{"t_x":"str"},{"t_y":[{"t_y1":"str"}]}]}]}]}];
var findStr = function(o) {
return _(o)
.map(function(v, k) {
return v === 'str'
? k
: _.isObject(v) ? findStr(v) : null;
})
.compact()
.flatten()
.value();
};
console.log(findStr(testArr));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
Я сделал это ... Я использовал lodash
. Мой код выглядит следующим образом:
var arrayData = [];
var teatData = [
{
"Attr": [
{
"power": { "p1": "str", "t3": "str" },
"light": [
{"test": "str"},
{"test2": [ { "t4": "str" }]}
]
}
]
},
{
"Attr1": [
{
"power1": { "p2": "str", "t5": "str" },
"light1": [
{ "test3": "str" },
{ "test_x": [
{ "t_x": "str" },
{ "t_y": [
{ "t_y1": "str" }
]
}
]
}
]
}
]
}
];
function getKeyArray(data, arrayData) {
if (Array.isArray(data)) {
_.forEach(data, (obj, key) => {
this.getKeyArray(obj, arrayData);
});
} else if (_.isPlainObject(data)) {
_.forEach(data, (obj, key) => {
if (obj === "str") {
arrayData.push(key);
} else if (Array.isArray(obj) || _.isPlainObject(obj)) {
this.getKeyArray(obj, arrayData);
}
});
}
}
getKeyArray(teatData, arrayData);
console.log(arrayData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>