我想在一个带有递归的Javascript嵌套对象中找到一个值的键。
下面是我对函数的尝试。有没有更优雅的方法来实现这一点?
null
const foo = { data: { data2: { data3: 'worked' }, data21: 'rand' }, data01: 'rand01' }
function findKey(obj, target) {
let result = null;
if (_.isEmpty(obj) || !_.isObject(obj)){
return null;
}
if (!_.isArray(obj) && Object.keys(obj).length > 0) {
for(let i=0; i < Object.keys(obj).length; i++){
let key = Object.keys(obj)[i];
let val = obj[key];
if (val === target) {
return key;
}else{
result = findKey(val, target);
}
if (result) {break}
}
}
return result;
}
console.log(findKey(foo, 'worked'))
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
null
例如,有没有一种方法可以避免检查result
的值然后中断?我觉得result应该能够在调用堆栈中冒泡,直到它在第一次函数调用时返回,而不必中断。
在上面提出的几个问题之后,该函数看起来应该:
OP提供的输入代码不处理数组情况。
对以下代码进行了采样,以便使用这些示例案例:
Below函数接受第二个参数,这是一个回调,用于评估met元素是否是我们要查找的元素。这样,处理更复杂的检查就更容易了。
保留递归方法,一旦满足键,函数只需return
,以避免不必要的搜索。
null
const foo = { data: { data2: { data3: 'worked' }, data21: 'rand' }, data01: 'rand01' };
const fooWithArrays = {
data: {
data2: {
data3: 'not here'
},
data4: [
{ data5: 'worked' },
{ data6: 'not me' }
]
}
};
const fooWithExpression = {
data: {
data2: {
data3: { id: 15, name: 'find me!' }
},
data21: {
data25: 'not me'
}
}
};
const findKeyByValue = (obj, equalsExpression) => {
// Loop key->value pairs of the input object.
for (var [key, v] of Object.entries(obj)) {
// if the value is an array..
if (Array.isArray(v)) {
// Loop the array.
for (let i = 0; i < v.length; i++) {
// check whether the recursive call returns a result for the nested element.
let res = findKeyByValue(v[i], equalsExpression);
// if so, the key was returned. Simply return.
if (res !== null && res !== undefined) return res;
}
}
// otherwise..
else {
// if the value is not null and not undefined.
if (v !== null && v !== undefined) {
// if the value is an object (typeof(null) would give object, hence the above if).
if (typeof(v) === 'object') {
// check whether the value searched is an object and the match is met.
if (equalsExpression(v)) return key;
// if not, recursively keep searching in the object.
let res = findKeyByValue(v, equalsExpression);
// if the key is found, return it.
if (res !== null && res !== undefined) return res;
}
else {
// finally, value must be a primitive or something similar. Compare.
let res = equalsExpression(v);
// if the condition is met, return the key.
if (res) return key;
// else.. continue.
}
}
else continue;
}
}
}
console.log( findKeyByValue(foo, (found) => found === 'worked') );
console.log( findKeyByValue(fooWithArrays, (found) => found === 'worked') );
console.log( findKeyByValue(fooWithExpression, (found) => found && found.id && found.id === 15) );
问题内容: 我试图找出如何递归地在此JSON对象中搜索节点。我尝试了一些但无法获得的东西: 这是我无法使用的解决方案,可能是因为当子节点在数组中时,第一个节点只是一个值: 问题答案: 您的代码只是缺少一个循环来检查数组中节点的每个子节点。此递归函数将返回节点的属性,或者如果树中不存在标签,则返回该属性: 您还可以使用显式堆栈进行迭代,该堆栈更快,更凉爽并且不会导致堆栈溢出:
我有一个LOCATION实体,它包含国家、州和城市。并且我有一个LocationRepository接口定义为: 我想按国家找到所有的州。我可以遵循方法名称标准来查询位置实体的所有内容。如果我想要列表,我需要创建StateRepository接口并在其中查询关于状态的一切吗?如果我可以从LocationRepository中获取它,那么方法是什么样子的?我假设它看起来会像下面这样(当然不起作用)。
问题内容: 我正在使用有角JS及其示例之一:http : //jsfiddle.net/furf/EJGHX/ 在发送更新功能之前,我需要获取数据并向其中添加一些值。(如果用angular而不是js更好,请告诉我) 我正在尝试获取“父代”和“索引”并更新子代。 这是我正在遍历的数据 这就是我目前正在遍历的方式,但是它只能得到第一个维度 我在另一个小提琴上找到了这个,但我不知道该如何抓取父对象或索引
问题内容: 我正在尝试从JSON对象动态构建表单,该对象包含表单元素的嵌套组: 我一直在使用ng-switch块,但是它与嵌套项变得站不住脚,就像上面的Address对象一样。 这是小提琴:http : //jsfiddle.net/hairgamiMaster/dZ4Rg/ 关于如何最好地解决此嵌套问题的任何想法?非常感谢! 问题答案: 我认为这可以为您提供帮助。它来自我在Google网上论坛上
问题内容: 我使用此代码从Jhonny的Question中的json 对象中找到了所需的部分 数据样本 查找功能 像这样使用: 此代码是从源代码中选择匹配的片段。但是我想要的是用新值更新源对象并检索更新的源对象。 我想要类似的东西 我的密码 如果我给定但如果我将代码更改为未定义的更新,则此方法有效。 为什么呢? 问题答案: 您忘记在嵌套调用中传递newValue
问题内容: 我在下面的对象中尝试获取所有id值。 使用以下代码,我仅获得第一个id值。有没有办法从嵌套对象中获取所有id值,而无需使用任何外部模块。 预期产量 问题答案: 您可以使用如下所示的JavaScript函数来获取嵌套属性: 检查此小提琴以获取可行的解决方案。