В фрагменте ниже, перед return(res)
, я запишу его, и он не undefined
но каким-то образом он возвращается как undefined
.
Что я делаю неправильно?
filterData = (inputData, searchedKey) => {
inputData.forEach((data, index) => {
if(data){
if(data.hasOwnProperty(searchedKey)){
const res = data[searchedKey]
console.log(res) /// logs the results
return(res) /// returns undefined
}
var dataToProcess = [];
var fieldKeys = Object.keys(data)
fieldKeys = fieldKeys.filter((field, index) => !field.includes("#"))
fieldKeys.forEach((key, index) => {
dataToProcess.push(data[key]);
})
this.filterData(dataToProcess, searchedKey)
}
})
}
console.log(this.filterData([{"#name": "foo", "#type": "bar"}], "#type"))
Некоторые вопросы:
forEach
не возвращает ничего, кроме undefined
, поэтому возврат значения в его функцию обратного вызова не делает ничего полезного.if (data)
недостаточно хороши, чтобы убедиться, что data
являются объектом. Например, это также верно для ненулевого числа. Вместо этого используйте Object(data) === data
.filter
стандартных массивов возвращает массив. Таким образом, это соответствовало бы этому.Вот как вы могли бы заставить его работать:
var filterData = (inputData, searchedKey) => {
inputData = inputData.filter( data => Object(data) === data );
return !inputData.length ? [] :
inputData.filter( data => data.hasOwnProperty(searchedKey) )
.map( data => data[searchedKey] )
// Add the results from recursion:
.concat(filterData([].concat(...
inputData.map( data =>
Object.keys(data)
.filter( key => !key.startsWith("#") )
.map( key => data[key] )
)
), searchedKey));
};
var data = [{
"#name": "foo",
"#title": "mr",
"deeper": [{
"#nope": "bad",
"deepest": [{
"nothing_here": null,
"#type": "deeper bar",
}]
}, {
"#type": "bar",
}]
}];
console.log(filterData(data, "#type"));
Если вам нужно только первое совпадение, используйте этот вариант:
var filterData = (inputData, searchedKey) => {
inputData = inputData.filter( data => Object(data) === data );
var res = inputData.find( data => data.hasOwnProperty(searchedKey) );
return res !== undefined ? res[searchedKey] :
// Try in nested objects:
filterData([].concat(...
inputData.map( data =>
Object.keys(data)
.filter( key => !key.startsWith("#") )
.map( key => data[key] )
)
), searchedKey);
};
var data = [{
"#name": "foo",
"#title": "mr",
"deeper": [{
"#nope": "bad",
"deepest": [{
"nothing_here": null,
"#type": "deeper bar",
}]
}, {
"#type": "bar",
}]
}];
console.log(filterData(data, "#type"));
Это то, чего вы хотите достичь?
filterData = (inputData, searchedKey) => {
return inputData.map((data, index) => {
if(data){
if(data.hasOwnProperty(searchedKey)){
const res = data[searchedKey]
console.log(res) /// logs the results
return(res) /// returns undefined
}
var dataToProcess = [];
var fieldKeys = Object.keys(data)
fieldKeys = fieldKeys.filter((field, index) => !field.includes("#"))
fieldKeys.forEach((key, index) => {
dataToProcess.push(data[key]);
})
this.filterData(dataToProcess, searchedKey)
}
})
}
console.log(this.filterData([{"#name": "foo", "#type": "bar"}], "#type"))
Используйте Array#map()
, это очень полезно во многих случаях.