JavaScript - 编辑嵌套对象

Posted

技术标签:

【中文标题】JavaScript - 编辑嵌套对象【英文标题】:JavaScript - Edit nested objects 【发布时间】:2022-01-20 08:24:21 【问题描述】:

我有一组嵌套对象。我想编辑它们中的每一个并添加属性 "status" 并且该属性的值可以是 "selected""unselected" 或 “缩进”。

1.状态:'选中'

他的 lvlScope 数组不为空 lvlScope 他所有孩子的数组不为空

2.状态:'未选中'

他的 lvlScope 数组为空 lvlScope 他所有孩子的数组都是空的

3.状态:'缩进'

他的 lvlScope 数组为空,并且他的至少一个孩子的 lvlScope 数组不为空 他的 lvlScope 数组不为空,并且他的至少一个孩子的 lvlScope 数组为空 他的 lvlScope 数组不为空,他所有的孩子都有 lvlScope 数组为空

所有子级表示所有嵌套的子级

有人知道怎么做吗?

let data = [
    id: 1,
    name: 'level1',
    lvlScope: [1, 2, 3],
    lvl1Subs: []
  ,
  
    id: 2,
    name: 'level1',
    lvlScope: [],
    lvl1Subs: [
        id: 1,
        name: 'level2',
        lvlScope: [],
        lvl2Subs: [
            id: 1,
            name: 'level3',
            lvlScope: [],
            lvl3Subs: []
          ,
          
            id: 2,
            name: 'level3',
            lvlScope: [1, 2],
            lvl3Subs: []
          ,
          
            id: 3,
            name: 'level3',
            lvlScope: [1],
            lvl3Subs: [
                id: 1,
                name: 'level4',
                lvlScope: [],
                lvl4Subs: [
                    id: 1,
                    name: 'level5',
                    lvlScope: []
                  ,
                  
                    id: 2,
                    name: 'level5',
                    lvlScope: [1]
                  
                ]
              ,
              
                id: 2,
                name: 'level4',
                lvlScope: [],
                lvl4Subs: []
              
            ]
          
        ]
      ,
      
        id: 2,
        name: 'level2',
        lvlScope: [1],
        lvl2Subs: []
      
    ]
  ,
  
    id: 3,
    name: 'level1',
    lvlScope: [],
    lvl1Subs: [
        id: 1,
        name: 'level2',
        lvlScope: [1, 2],
        lvl2Subs: []
      ,
      
        id: 2,
        name: 'level2',
        lvlScope: [],
        lvl2Subs: []
      ,
      
        id: 3,
        name: 'level2',
        lvlScope: [1, 2, 3],
        lvl2Subs: [
          id: 1,
          name: 'level3',
          lvlScope: [],
          lvl3Subs: []
        ]
      ,
      
        id: 4,
        name: 'level2',
        lvlScope: [],
        lvl2Subs: []
      ,
      
        id: 5,
        name: 'level2',
        lvlScope: [1, 2],
        lvl2Subs: []
      
    ]
  
]

const levels = (data) => 

  data.map((lvl1) => 
    console.log('-lvl1', lvl1)
    lvl1.lvl1Subs.map((lvl2) => 
      console.log('--lvl2', lvl2)
      lvl2.lvl2Subs.map((lvl3) => 
        console.log('---lvl3', lvl3)
        lvl3.lvl3Subs.map((lvl4) => 
          console.log('----lvl4', lvl4)
          lvl4.lvl4Subs.map((lvl5) => 
            console.log('-----lvl5', lvl5)
          )
        )
      )
    )
  )


console.log(levels(data))

【问题讨论】:

您能否详细说明您为实现预期结果所做的工作?您已经有了一些代码,用于显示/打印您可以开始的不同级别。此外,您可能希望研究递归来解决其中的一些问题。 【参考方案1】:

当关卡没有子级时,您没有说明要分配什么。此外,尚不清楚检查是否应该仅针对直接子级或嵌套子级进行。这是一个解决方案,考虑到没有孩子意味着 selectedunselected 并考虑仅对直接孩子进行检查。

const addStatus = (data, level = 1) => 
  const scope = emptyScope(data);
  let childrenScopes = [];
  for (let child of data["lvl" + level + "Subs"]
    ? data["lvl" + level + "Subs"]
    : []) 
    childrenScopes.push(emptyScope(child));
    addStatus(child, level + 1);
  

  let status = "indent";
  let found = childrenScopes.find((c) => c === !scope);
  if (found === true || found === false) 
    found = true;
   else 
    found = false;
  
  if ((!found || !childrenScopes.length) && !scope) 
    status = "selected";
  
  if ((!found || !childrenScopes.length) && scope) 
    status = "unselected";
  

  data["status"] = status;
;

const emptyScope = (data) => 
  if (data.lvlScope.length > 0) 
    return false;
  
  return true;
;

data.map((d) => addStatus(d, 1));

console.log(data);

在评论中提供信息后进行编辑

const addStatus = (data, level = 1) => 
  const scope = emptyScope(data);
  let childrenScopes = childScopes(data, level, []);

  let status = "indent";
  let found = typeof childrenScopes.find((c) => c === !scope) === "boolean";

  if ((!found || !childrenScopes.length) && !scope) 
    status = "selected";
  
  if ((!found || !childrenScopes.length) && scope) 
    status = "unselected";
  

  data["status"] = status;

  for (let child of data["lvl" + level + "Subs"]
    ? data["lvl" + level + "Subs"]
    : []) 
    addStatus(child, level + 1);
  
;

const childScopes = (data, level, scopes) => 
  for (let child of data["lvl" + level + "Subs"]
    ? data["lvl" + level + "Subs"]
    : []) 
    scopes.push(emptyScope(child));
    childScopes(data["lvl" + level + "Subs"], level, scopes);
  
  return scopes;
;

const emptyScope = (data) => 
  if (data.lvlScope.length > 0) 
    return false;
  
  return true;
;

data.map((d) => addStatus(d, 1));

console.log(data);

【讨论】:

如果 level 没有子级,它只依赖于它自己。如果 lvlScope 为空则应为“未选中”,如果 lvlScope 不为空则应为“选中”。检查也应该在嵌套的孩子中完成。 请尝试检查编辑【参考方案2】:

你可以用递归函数的方式轻松解决这个问题。

【讨论】:

以上是关于JavaScript - 编辑嵌套对象的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 如何查找嵌套中的element对象

JavaScript对象

使用javascript循环读取JSON数字数组[重复]

document和javaScript内置对象

测试嵌套 JavaScript 对象键是不是存在

测试嵌套 JavaScript 对象键是不是存在