Javascript 快速访问json树数据结构

Javascript 快速访问json树数据结构,javascript,reactjs,redux,redux-toolkit,Javascript,Reactjs,Redux,Redux Toolkit,我有一个保存树数据结构的reducer(总共超过10万项)。这就是数据的样子 [ { text: 'A', expanded: false, items: [ { text: 'AA', expanded: false }, { text: 'AB',

我有一个保存树数据结构的reducer(总共超过10万项)。这就是数据的样子

[
    {
        text: 'A',
        expanded: false,
        items:
        [
            {
                text: 'AA',
                expanded: false
            },
            {
                text: 'AB',
                expanded: false,
                items:
                [
                    {
                        text: 'ABA',
                        expanded: false,
                    },
                    {
                        text: 'ABB',
                        expanded: false,
                    }
                ]
            }
        ]
    },
    {
        text: 'B',
        expanded: false,
        items:
        [
            {
                text: 'BA',
                expanded: false
            },
            {
                text: 'BB',
                expanded: false
            }
        ]
    }
]

我需要做的是使用文本作为id快速访问这些项目(每次用户单击树视图中的项目时需要切换展开)。我应该将整个结构复制到字典中,还是有更好的方法?

将所有单个项目复制到
映射中,然后通过ID访问它

const data=[]//您的数据
//建立地图索引
const itemsMap=新映射();
让itemsQueue=[…数据];
让cursor=itemsQueue.pop();
while(光标){
itemsMap.set(cursor.text,cursor);
if(游标项目)
for(让项目成为游标。项目){
itemsQueue.push(项目);
}
cursor=itemsQueue.pop();
}
//按文本id检索
console.log(map.get('ABB'));
// {
//文本:“ABB”,
//扩展:错,
// }

将所有单个项目复制到
地图中,然后通过ID访问该地图

const data=[]//您的数据
//建立地图索引
const itemsMap=新映射();
让itemsQueue=[…数据];
让cursor=itemsQueue.pop();
while(光标){
itemsMap.set(cursor.text,cursor);
if(游标项目)
for(让项目成为游标。项目){
itemsQueue.push(项目);
}
cursor=itemsQueue.pop();
}
//按文本id检索
console.log(map.get('ABB'));
// {
//文本:“ABB”,
//扩展:错,
// }

我认为您的意思可能是处理扩展更改的成本非常高(因为您可能关闭/打开一个有100000个叶子的节点,然后通知100000个UI项)

但是,这让我担心,因为我希望只存在扩展的UI项(例如,您没有为所有内容隐藏React元素,每个元素都位于那里,并监控Redux选择器,以防其树的一部分可见)

只要元素在未展开时不存在,那么为什么展开状态除了它的直接父级之外,其他任何东西都知道,并且如果它也在屏幕上,只有父级知道


我建议扩展状态应该是React状态,而不是Redux状态。如果它们在屏幕上,那么它们就被扩展,可以选择扩展它们的子元素(在父UI元素中保持为状态),如果它们不在屏幕上,它们就不存在。

我认为您可能意味着处理扩展更改的成本非常高(因为可能会关闭/打开一个有100000个叶子的节点,然后会通知100000个UI项)

但是,这让我担心,因为我希望只存在扩展的UI项(例如,您没有为所有内容隐藏React元素,每个元素都位于那里,并监控Redux选择器,以防其树的一部分可见)

只要元素在未展开时不存在,那么为什么展开状态除了它的直接父级之外,其他任何东西都知道,并且如果它也在屏幕上,只有父级知道


我建议扩展状态应该是React state,而不是Redux state。如果它们在屏幕上,那么它们将被扩展,可以选择扩展它们的子元素(在父UI元素中作为状态保留)如果它们不在屏幕上,它们就不存在。

以下内容可能会有所帮助,如果您需要更多帮助,请告诉我,但请创建一个可运行的示例(代码段)来说明问题:

const项=[
{
正文:“A”,
扩展:错,
项目:[
{
正文:“AA”,
扩展:错,
},
{
文本:“AB”,
扩展:错,
项目:[
{
文本:“ABA”,
扩展:错,
},
{
文本:“ABB”,
扩展:错,
},
],
},
],
},
{
正文:“B”,
扩展:错,
项目:[
{
正文:“BA”,
扩展:错,
},
{
文本:“BB”,
扩展:错,
},
],
},
];
//在你的减速机里
const mapItems=新映射();
const createMap=(项目)=>{
常量重复=(路径)=>(项目,索引)=>{
const currentPath=path.concat(索引);
mapItems.set(item.text,currentPath);
//在此路径中未找到任何子项
如果(!item.items){
返回;
}
//递归集映射
item.items.forEach(recur(currentPath));
};
//清除地图
mapItems.clear();
//重新创建地图
项目。每项(重复([]);
};
常量递归更新=(路径、项目、更新)=>{
常量重复=([当前,…路径])=>(项目,索引)=>{
if(index==当前路径长度){
//没有其他要更改的子项
返回{…项,…更新};
}
如果(索引==当前){
//需要更改item.items中的项目
返回{
…项目,
items:item.items.map(重现(路径)),
};
}
//这件事没什么可做的
退货项目;
};
返回项。映射(递归(路径));
};
const reducer=(状态、操作)=>{
//如果设置数据,然后创建地图,则可以
//测试很困难,因为SET_项仅在以下情况下工作
//当您首先调用SET_DATA时。您不应该
//减速器中的副作用(如创建地图)
//为了优化,我打破了这个规则
如果(action.type==='SET_DATA'){
createMap(action.payload);//创建映射
返回{…状态,项};
}
如果(action.type==='SET\u ITEM'){
返回{
……国家,
项目:递归更新(
mapItems.get(action.payload.text),
国家项目,
行动.有效载荷
),
};
}
返回状态;
};
//装箱
常数状态=减速机(
{},
{type:'SET_DATA',有效负载:items}
);
const changed1=减速器(状态{
类型:“设置项目”,
有效负载:{text:'A',changed:'A'},
});
常数{
物品:不见了,
…不含ubitems
}=changed1.项目[0];
console.log('1',不带ubitems);
const changed2=减速器(状态{
类型:“设置项目”,
有效负载:{text:'ABB',已更改:'ABB'},
});
console.log('2',changed2.items[0]。items[1]。items[1]);
常数