首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从数组的层次对象创建路径数组

如何从数组的层次对象创建路径数组
EN

Stack Overflow用户
提问于 2022-10-12 00:12:12
回答 2查看 71关注 0票数 0

我需要基于数组的分层对象的选定属性创建路径数组。路径以索引的形式出现,以反斜杠分隔,例如0/0/0。

场景1:selected is none

不需要存储路径

场景2:selected是部分的--这是我有问题的

不需要存储当前节点的路径,但是需要存储具有选定值的子节点的路径--所有

场景3:所选

当前节点及其所有子节点的路径需要存储。

预期结果:'0‘、'0/0’、'0/0/0‘、'0/0/1’、'0/1/0‘、’0/1/0‘、'0/1/1’、'1/0/0'

当前逻辑结果:"0“、"0/0”、"0/0/1“、"1”、"1/0“

代码语言:javascript
复制
treeData = [{
    name: 'Infiniti',
    selected: 'all',
    children: [{
        name: 'G50',
        selected: 'all',
        children: [{
            name: 'Pure AWD',
            selected: 'all',
          },
          {
            name: 'Luxe',
            selected: 'all',
          },
        ],
      },
      {
        name: 'QX50',
        selected: 'all',
        children: [{
            name: 'Pure AWD',
            selected: 'all',
          },
          {
            name: 'Luxe',
            selected: 'all',
          },
        ],
      },
    ],
  },
  {
    name: 'BMW',
    selected: 'partial',
    children: [{
        name: '2 Series',
        selected: 'partial',
        children: [{
            name: 'Coupé',
            selected: 'all',
          },
          {
            name: 'Gran Coupé',
            selected: 'none',
          },
        ],
      },
      {
        name: '3 Series',
        selected: 'none',
        children: [{
            name: 'Sedan',
            selected: 'none',
          },
          {
            name: 'PHEV',
            selected: 'none',
          },
        ],
      },
    ],
  },
];

indexPathArray = [];
path = '';

function arrayOfIndexPaths() {
  for (let i = 0; i < treeData.length; i++) {
    if (treeData[i].selected === 'all' || treeData[i].selected === 'partial') {
      indexPathArray.push(i.toString());
      if (treeData[i].children) {
        updateIndexPaths(i, treeData[i].children);
      }
    }
  }
  return indexPathArray;
}

function updateIndexPaths(parentIndex, nodes) {
  path = parentIndex;
  for (let j = 0; j < nodes.length; j++) {
    if (nodes[j].selected === 'all') {
      path = path + '/' + j;
      indexPathArray.push(path);
    } else if (nodes[j].selected === 'partial' && nodes[j].children != null) {
      this.updateIndexPaths(path, nodes[j].children);
    }
  }
}

console.log(arrayOfIndexPaths());

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-12 04:18:07

下文介绍的是实现预期目标的一种可能方法。

代码片段

代码语言:javascript
复制
// helper method to iterate each array elt
// detailed explanation of code is below
const myIterator = (children, idx, noCheck, paths, parentPath) => {
  const currPath = parentPath?.length ? `${parentPath}/${idx}` : idx?.toString();
  if (noCheck) paths.push(currPath);
  if (children?.length) return getAllSelectedPaths(
    children, noCheck, paths, currPath
  );
  else return paths;
};

// main method to get paths when selected is 'all' or 'partial'
// detailed explanation of code is below
const getAllSelectedPaths = (
  arr = [], noCheck = false, paths = [], parentPath = ''
) => (
  (noCheck) ? (
    arr?.reduce(
      (acc, { children }, idx) => {
        acc = myIterator(children, idx, noCheck, acc, parentPath);
        return acc;
      }, 
      paths
    )
  ) : (
    arr?.reduce(
      (acc, { children = [], selected }, idx) => {
        if (['all', 'partial']?.includes(selected)) {
          acc = myIterator(children, idx, selected === 'all', acc, parentPath);
        };
        return acc;
      },
      paths
    )
  )
);

/*
// helper method to iterate each array elt
// arguments description
// children - array of children in the parent elt
// idx - array index of parent
// noCheck - flag to determine whether (or not) to look at 'selected'
// this is useful when parent is 'all' so we process accordingly
// paths - current list of paths
// parentPath - the path to the parent elt

const myIterator = (children, idx, noCheck, paths, parentPath) => {
  // first determine the "current path" as currPath
  // suffix parent's path with "idx"
  const currPath = parentPath?.length ? `${parentPath}/${idx}` : idx?.toString();
  
  // if flag "noCheck" is true, add currPath to paths array
  if (noCheck) paths.push(currPath);
  
  // if there are elts in "children" array, process those
  if (children?.length) return getAllSelectedPaths(
    children, noCheck, paths, currPath
  );
  
  // else (ie, children is empty), simply return current "paths" array
  else return paths;
};

// main method to get paths when selected is 'all' or 'partial'
// arguments description

// arr - current array being processed (initially it will be the outermost array)
// noCheck - flag to determine whether selected needs to be considered on children
// paths - array of paths
// parentPath - path of the parent elt

const getAllSelectedPaths = (
  arr = [], noCheck = false, paths = [], parentPath = ''
) => (
  // if the flag "noCheck" is true (ie, we don't need to look for "selected")
  (noCheck) ? (
    // simply reduce current array with "noCheck" as true
    // it will update the paths (include elts "0", "0/0", "0/1", etc)
    arr?.reduce(
      (acc, { children }, idx) => {
        acc = myIterator(children, idx, noCheck, acc, parentPath);
        return acc;
      }, 
      paths
    )
  ) : (
    // flag "noCheck" is false
    // so, we discard any elt where "selected" is not "all" or "partial"
    // same "reduce" as earlier, but in this case the noCheck is determined based on
    // "selected" being "all" (true) or "partial" (false)
    arr?.reduce(
      (acc, { children = [], selected }, idx) => {
        if (['all', 'partial']?.includes(selected)) {
          acc = myIterator(children, idx, selected === 'all', acc, parentPath);
        };
        return acc;
      },
      paths
    )
  )
);
*/

const treeData = [{
    name: 'Infiniti',
    selected: 'all',
    children: [{
        name: 'G50',
        selected: 'all',
        children: [{
            name: 'Pure AWD',
            selected: 'all',
          },
          {
            name: 'Luxe',
            selected: 'all',
          },
        ],
      },
      {
        name: 'QX50',
        selected: 'all',
        children: [{
            name: 'Pure AWD',
            selected: 'all',
          },
          {
            name: 'Luxe',
            selected: 'all',
          },
        ],
      },
    ],
  },
  {
    name: 'BMW',
    selected: 'partial',
    children: [{
        name: '2 Series',
        selected: 'partial',
        children: [{
            name: 'Coupé',
            selected: 'all',
          },
          {
            name: 'Gran Coupé',
            selected: 'none',
          },
        ],
      },
      {
        name: '3 Series',
        selected: 'none',
        children: [{
            name: 'Sedan',
            selected: 'none',
          },
          {
            name: 'PHEV',
            selected: 'none',
          },
        ],
      },
    ],
  },
];

console.log(
  'paths to selected=all are:\n',
  getAllSelectedPaths(treeData)
);
代码语言:javascript
复制
.as-console-wrapper { max-height: 100% !important; top: 0 }

解释

将内联注释添加到上面的片段中。

票数 0
EN

Stack Overflow用户

发布于 2022-10-12 09:25:52

国际海事组织。规则并没有那么复杂:

selected="all":加入我,检查我的孩子。

selected="partial":不要加我,而是检查我的孩子。

selected="none":不要加我,不要检查我的孩子。

代码语言:javascript
复制
const treeData = [{
    name: 'Infiniti',
    selected: 'all',
    children: [{
        name: 'G50',
        selected: 'all',
        children: [{
            name: 'Pure AWD',
            selected: 'all',
          },
          {
            name: 'Luxe',
            selected: 'all',
          },
        ],
      },
      {
        name: 'QX50',
        selected: 'all',
        children: [{
            name: 'Pure AWD',
            selected: 'all',
          },
          {
            name: 'Luxe',
            selected: 'all',
          },
        ],
      },
    ],
  },
  {
    name: 'BMW',
    selected: 'partial',
    children: [{
        name: '2 Series',
        selected: 'partial',
        children: [{
            name: 'Coupé',
            selected: 'all',
          },
          {
            name: 'Gran Coupé',
            selected: 'none',
          },
        ],
      },
      {
        name: '3 Series',
        selected: 'none',
        children: [{
            name: 'Sedan',
            selected: 'none',
          },
          {
            name: 'PHEV',
            selected: 'none',
          },
        ],
      },
    ],
  },
];

const collect = (array, prefix, acc) => array ?
  array.reduce((acc, {selected, children}, i) => {
    if (selected === "all") {
      acc.push(prefix + i);
    } else if (selected !== "partial") {
      return acc;
    }

    return collect(children, prefix + i + "/", acc);
  }, acc) :
  acc;

console.log(collect(treeData, "", []));

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74035213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档