在深度嵌套的对象数组中查找最大 id 值
Find maximum id value in a deeply nested array of objects
我有一个树数据结构,每个对象都包含子对象:
const data = {
id: 1,
name: "John",
parent_id: null,
children: [{
id: 2,
name: "Tess",
parent_id: 1,
children: []
},
{
id: 3,
name: "Tom",
parent_id: 1,
children: [{
id: 4,
name: "Harry",
parent_id: 3,
children: [{
id: 7,
name: "Thabo",
parent_id: 4,
children: []
}]
},
{
id: 5,
name: "Mary",
parent_id: 3,
children: []
},
{
id: 6,
name: "Madge",
parent_id: 3,
children: []
}
]
}
]
}
在向树中添加新对象之前,我需要确定当前使用的最高 id
值,以便为新用户分配下一个可用编号 id
。
为此,我创建了一个初始值为 0 的新变量。然后我遍历树中的每个对象,如果对象的 id
高于新的 id,我将新的分配给id 当前 id 的值(想法是取最终值并加 1 以获得新 id)。
let newUserID = 0;
const newID = ( root, idKey ) => {
if ( root.id > idKey ) {
idKey = root.id;
}
root.children.forEach( ( obj ) => {
newID( obj, idKey );
});
return idKey;
}
newUserID = newID( data, newUserID );
console.log( newUserID );
我希望这个 return 树中最高的 id
作为最终值,但实际发生的是,虽然新的 id 确实增加直到它匹配最大值,但它然后再次开始减少,以 1 结束。
这可以在这个 JSFiddle 中看到,其中包括一些日志记录以显示函数中不同点的新 ID 的值。
我已经使用不同的方法解决了这个问题(将 id
值提取到一个新数组,并使用 Math.max()
找到最大值),但我想理解为什么我最初的方法没有按预期工作。我可以看到 idKey
值正在更新,但之前的值在递归调用中被传回,但我不知道为什么会这样或如何防止它。
你可以使用递归来解决这个问题。喜欢下面
const data = {
id: 1,
name: "John",
parent_id: null,
children: [
{
id: 2,
name: "Tess",
parent_id: 1,
children: [],
},
{
id: 3,
name: "Tom",
parent_id: 1,
children: [
{
id: 4,
name: "Harry",
parent_id: 3,
children: [
{
id: 7,
name: "Thabo",
parent_id: 4,
children: [],
},
],
},
{
id: 5,
name: "Mary",
parent_id: 3,
children: [],
},
{
id: 6,
name: "Madge",
parent_id: 3,
children: [],
},
],
},
],
};
const findMax = (value) => {
let max = -Infinity;
const _findMax = (data) => {
if (max < data.id) max = data.id;
data.children.forEach(_findMax);
};
_findMax(value);
return max;
};
console.log(findMax(data));
简单的将递归调用的返回值赋值给idKey
:
let newUserID = 0;
const newID = ( root, idKey ) => {
if ( root.id > idKey ) {
idKey = root.id;
}
root.children.forEach( ( obj ) => {
idKey = newID( obj, idKey ); // <--------
});
return idKey;
}
newUserID = newID( data, newUserID );
console.log( newUserID );
如果没有这个赋值,无论你递归多少次,返回的值都将只取决于顶部if
语句的结果。这解释了您收到的日志。
你可以这样做:
const data = {id: 1,name: 'John',parent_id: null,children: [{ id: 2, name: 'Tess', parent_id: 1, children: [] },{id: 3,name: 'Tom',parent_id: 1,children: [{id: 4,name: 'Harry',parent_id: 3,children: [{ id: 7, name: 'Thabo', parent_id: 4, children: [] }],},{ id: 5, name: 'Mary', parent_id: 3, children: [] },{ id: 6, name: 'Madge', parent_id: 3, children: [] },],},],}
const arr = [...JSON.stringify(data).matchAll(/"id":(\d+)/g)].map(([, n]) => +n)
const result = Math.max(...arr)
console.log(result)
首先,关于您的代码被破坏的原因:您只是错过了一项作业。你在哪里
newID( obj, idKey );
您忽略了结果值。您需要将其分配回 idKey
:
idKey = newID( obj, idKey );
这将解决您的问题。我们还应注意,变量名称 newUserID
有点用词不当,因为它 不是 您将使用的新变量,而是找到的最高变量。也许 highestUserID
不会那么混乱?
但是,我们应该指出,这可以写得更简单,使用 Math .max
来完成繁重的工作和一些递归。我可能会这样写:
const maxId = ({id, children = []}) =>
Math .max (id, ... children .map (maxId))
const data = {id: 1, name: "John", parent_id: null, children: [{id: 2, name: "Tess", parent_id: 1, children: []}, {id: 3, name: "Tom", parent_id: 1, children: [{id: 4, name: "Harry", parent_id: 3, children: [{id: 7, name: "Thabo", parent_id: 4, children: []}]}, {id: 5, name: "Mary", parent_id: 3, children: []}, {id: 6, name: "Madge", parent_id: 3, children: []}]}]}
console .log (maxId (data))
我有一个树数据结构,每个对象都包含子对象:
const data = {
id: 1,
name: "John",
parent_id: null,
children: [{
id: 2,
name: "Tess",
parent_id: 1,
children: []
},
{
id: 3,
name: "Tom",
parent_id: 1,
children: [{
id: 4,
name: "Harry",
parent_id: 3,
children: [{
id: 7,
name: "Thabo",
parent_id: 4,
children: []
}]
},
{
id: 5,
name: "Mary",
parent_id: 3,
children: []
},
{
id: 6,
name: "Madge",
parent_id: 3,
children: []
}
]
}
]
}
在向树中添加新对象之前,我需要确定当前使用的最高 id
值,以便为新用户分配下一个可用编号 id
。
为此,我创建了一个初始值为 0 的新变量。然后我遍历树中的每个对象,如果对象的 id
高于新的 id,我将新的分配给id 当前 id 的值(想法是取最终值并加 1 以获得新 id)。
let newUserID = 0;
const newID = ( root, idKey ) => {
if ( root.id > idKey ) {
idKey = root.id;
}
root.children.forEach( ( obj ) => {
newID( obj, idKey );
});
return idKey;
}
newUserID = newID( data, newUserID );
console.log( newUserID );
我希望这个 return 树中最高的 id
作为最终值,但实际发生的是,虽然新的 id 确实增加直到它匹配最大值,但它然后再次开始减少,以 1 结束。
这可以在这个 JSFiddle 中看到,其中包括一些日志记录以显示函数中不同点的新 ID 的值。
我已经使用不同的方法解决了这个问题(将 id
值提取到一个新数组,并使用 Math.max()
找到最大值),但我想理解为什么我最初的方法没有按预期工作。我可以看到 idKey
值正在更新,但之前的值在递归调用中被传回,但我不知道为什么会这样或如何防止它。
你可以使用递归来解决这个问题。喜欢下面
const data = {
id: 1,
name: "John",
parent_id: null,
children: [
{
id: 2,
name: "Tess",
parent_id: 1,
children: [],
},
{
id: 3,
name: "Tom",
parent_id: 1,
children: [
{
id: 4,
name: "Harry",
parent_id: 3,
children: [
{
id: 7,
name: "Thabo",
parent_id: 4,
children: [],
},
],
},
{
id: 5,
name: "Mary",
parent_id: 3,
children: [],
},
{
id: 6,
name: "Madge",
parent_id: 3,
children: [],
},
],
},
],
};
const findMax = (value) => {
let max = -Infinity;
const _findMax = (data) => {
if (max < data.id) max = data.id;
data.children.forEach(_findMax);
};
_findMax(value);
return max;
};
console.log(findMax(data));
简单的将递归调用的返回值赋值给idKey
:
let newUserID = 0;
const newID = ( root, idKey ) => {
if ( root.id > idKey ) {
idKey = root.id;
}
root.children.forEach( ( obj ) => {
idKey = newID( obj, idKey ); // <--------
});
return idKey;
}
newUserID = newID( data, newUserID );
console.log( newUserID );
如果没有这个赋值,无论你递归多少次,返回的值都将只取决于顶部if
语句的结果。这解释了您收到的日志。
你可以这样做:
const data = {id: 1,name: 'John',parent_id: null,children: [{ id: 2, name: 'Tess', parent_id: 1, children: [] },{id: 3,name: 'Tom',parent_id: 1,children: [{id: 4,name: 'Harry',parent_id: 3,children: [{ id: 7, name: 'Thabo', parent_id: 4, children: [] }],},{ id: 5, name: 'Mary', parent_id: 3, children: [] },{ id: 6, name: 'Madge', parent_id: 3, children: [] },],},],}
const arr = [...JSON.stringify(data).matchAll(/"id":(\d+)/g)].map(([, n]) => +n)
const result = Math.max(...arr)
console.log(result)
首先,关于您的代码被破坏的原因:您只是错过了一项作业。你在哪里
newID( obj, idKey );
您忽略了结果值。您需要将其分配回 idKey
:
idKey = newID( obj, idKey );
这将解决您的问题。我们还应注意,变量名称 newUserID
有点用词不当,因为它 不是 您将使用的新变量,而是找到的最高变量。也许 highestUserID
不会那么混乱?
但是,我们应该指出,这可以写得更简单,使用 Math .max
来完成繁重的工作和一些递归。我可能会这样写:
const maxId = ({id, children = []}) =>
Math .max (id, ... children .map (maxId))
const data = {id: 1, name: "John", parent_id: null, children: [{id: 2, name: "Tess", parent_id: 1, children: []}, {id: 3, name: "Tom", parent_id: 1, children: [{id: 4, name: "Harry", parent_id: 3, children: [{id: 7, name: "Thabo", parent_id: 4, children: []}]}, {id: 5, name: "Mary", parent_id: 3, children: []}, {id: 6, name: "Madge", parent_id: 3, children: []}]}]}
console .log (maxId (data))