我需要基于数组的分层对象的选定属性创建路径数组。路径以索引的形式出现,以反斜杠分隔,例如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“
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());
发布于 2022-10-12 04:18:07
下文介绍的是实现预期目标的一种可能方法。
代码片段
// 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)
);.as-console-wrapper { max-height: 100% !important; top: 0 }
解释
将内联注释添加到上面的片段中。
发布于 2022-10-12 09:25:52
国际海事组织。规则并没有那么复杂:
selected="all":加入我,检查我的孩子。
selected="partial":不要加我,而是检查我的孩子。
selected="none":不要加我,不要检查我的孩子。
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, "", []));
https://stackoverflow.com/questions/74035213
复制相似问题