递归迭代对象数组以求和包总数

huangapple go评论61阅读模式
英文:

Recursively iterate through Object Array to sum package totals

问题

我有一个项目数组,其中一些项目被视为包裹。这些包裹可以嵌套在彼此内部,最多可以有X层级。这些包裹也可以被折叠,但每个级别的包裹的总金额必须包括其子级。

确定包裹的开始是"BP"(Begin Package),结束是"EP"(End Package)。但是,如果包裹被折叠,"EP"项目不会存在于项目数组中。但是包裹的总金额需要计入其中。

我困扰于如何跟踪哪个包裹嵌套在另一个包裹中,以及如何计算嵌套包裹的总金额并在父级总金额中计算这些嵌套总额。

数据数组:

[
 { id: "BP", collapsed: false },
 { id: 1 },
 { id: 2 },
 { id: "BP", collapsed: false },
 { id: 3 },
 { id: "BP", collapsed: true },
 { id: 4 },
 { id: "EP" },
 { id: "EP" }, 
]

嵌套的结果应该是:

BP
1
2
   BP
   3
      BP
      // 折叠的项目
      5
      EP
   4
   EP
EP

这里的"id"表示这是普通项目,当计算包裹总额时,它将包括在包裹项目中,没有包括帮助确定它是否在包裹中,或包裹的开始或结束的属性。但是它将对包裹总额有贡献。

问题在于我无法轻松地迭代项目,因为第三个包裹的"EP"不存在,因此我无法想出一种方法来上升到第二层,因为我不会遇到该项目的"EP",以确定包裹的结束。但我需要计算根包裹的总金额并包括所有子级,以及计算子包裹,它们也将包括其子级。

目前,包裹被限制在最多嵌套3层深,但如果可能的话,我希望支持使用递归无限嵌套项目。

任何帮助都将非常有用,我已经盯着同样的问题几天了。非常感谢您提前的帮助!

我尝试使用for循环迭代项目,使用"BP"和"EP"项目来跟踪级别。

例如:

var epNeeded = 0;
var nestedPkgNum = -1;
var pkgItems = [];
var nestedPkgLines = [];

for (var i = 0, size = items.length; i < size; i++) {
 if (epNeeded === 0 && item.id === "BP") {
  if (!item.collapsed) {
   epNeeded++;
  }
 }

 // 如果需要"EP"大于0,则它将嵌套在根包裹中
 else if (epNeeded > 0 && item.id === "BP") {
  nestedPkgNum++;
  
  if (!item.collapsed) {
   epNeeded++;
  }
 }

 else if (item.id === "EP") {
  if (epNeeded > 1) {
   epNeeded--;
   // 计算子包裹
  }

  // 根包裹结束
  if (epNeeded === 1) {
   epNeeded = 0;
   
   // 计算所有包裹项目
  }
 }
 
 else if (epNeeded > 1) {
  nestedPkgLines[nestedPkgNum].push(item);
 }

 else if (epNeeded === 1) {
  pkgItems.push(item);
 }
}

//结果:
// pkgItems
[
  {id: 1}, 
  {id: 2}
]

// nestedPkgLines
[
  0: [{id: 3}, {id: 4}],
  1: [{id: 5}]
]

结果的问题在于,当我到达第三层嵌套时,它会作为另一个数组添加到nestedPkgLines中,因此只会计算根包裹的总金额,而不会计算第二级包裹的总金额。

我已经让第二级嵌套的项目正常工作,因为我可以跟踪根包裹和第二级嵌套包裹中的项目,但我无法找到一种方法来跟踪第三级嵌套中的项目,并将其与其包裹相关联,以便计算包裹的总金额,然后在根包裹的总和中使用该包裹的总金额。

英文:

I have an array of items and some items in the array are considered to be packages. The packages can be nested inside of each other to X number of levels. The packages are also able to be collapsed but the total dollar amount of the package at each level has to account for its children.

The way to determine the start of a package would be a BP (Begin Package), and the end of a package would be a EP (End Package). However if the package is collapsed, the EP item does not exist in the items array. However the totals of the packages need to be accounted for.

Stuck on trying to figure out a way to keep track of which package is nested in another package and how to total the nested packages and account for those nested totals in the parent total.

Data Array:

[
 { id: BP, collapsed: false },
 { id: 1 },
 { id: 2 },
 { id: BP, collapsed: false },
 { id: 3 },
 { id: BP, collapsed: true },
 { id: 4 },
 { id: EP },
 { id: EP }, 
]

Result nesting should be:
BP
1
2
   BP
   3
      BP
      // Collapsed Items
      5
      EP
   4
   EP
EP

id = item just means it is a regular item and it will be included in the package items when calculating the package totals, there are no properties included that help determine if it is inside a package or the start or end of a package. However It will contribute to the package sum when calculating totals.

The issue here is that I cant iterate over the items easily because the EP for the 3rd package does not exist, therefore I cant think of a way to go up to the 2nd level since I wont encounter an EP for that item to determine the end of the package. But I need to total the root package and include all the children, as well as total the child packages that will also include their children.

Right now the package are limited to nesting 3 levels deep however if possible I would like to support infinitely nesting items using recursion if possible.

Any help at all would be amazing, ive been staring at the same issue for days now. Thank you in advance!!!

Ive tried iterating using a for loop using the Bp and Ep items to keep track of level.

Ex.

var epNeeded = 0;
var nestedPkgNum = -1;
var pkgItems = [];
var nestedPkgLines = [][];

for (var i = 0, size = items.length, i &lt; size; i++) {
 if (epNeeded === 0 &amp;&amp; item.id === &quot;BP&quot;) {
  if (!item.collapsed) {
   epNeeded++
  }
 }

 // If EP needed greater than 0, then it would be nested in root package
 else if (epNeeded &gt; 0 &amp;&amp; item.id === &quot;BP&quot;) {
  nestedPkgNum++;
  
  if (!item.collapsed) {
   epNeeded++
  }
 }

 else if (item.id === &quot;EP&quot;) {
  if (epNeeded &gt; 1) {
   epNeeded--;
   // Sum child package
  }

  // End of root package
  if (epNeeded === 1) {
   epNeeded = 0;
   
   // Sum all package items
  }
 }
 
 else if (epNeeded &gt; 1) {
  nestedPkgLines[nestedPkgNum].push(item)
 }

 else if (epNeeded === 1) {
  pkgLines.push(item)
 }
}

//Result:
// pkgItems
[
  {id: 1}, 
  {id: 2}
]

// nestedPkgLines
[
  0: [{id: 3}, {id: 4}],
  1: [{id: 5}]
]

The issue with result is that when I get to the 3rd level of nesting, it adds to nestedPkgLines as another array and therefore only counts for the root package total and not for the total of the 2nd level package as well.

I have gotten this to work for the 2nd level of nesting because I can keep track of items in a root package and a 2nd level nested package but I cant determine a way to keep track of the items in a 3rd level of nesting and associate them with their package so I can total the package and then use that package total in the sum for the root package.

答案1

得分: 1

我不完全理解你的问题,但这个答案可能会帮助你明确问题:

const data = [{"id":"BP","collapsed":false},{"id":"item"},{"id":"item"},{"id":"BP","collapsed":false},{"id":"item"},{"id":"BP","collapsed":true},{"id":"item"},{"id":"EP"},{"id":"EP"}]

const root = {}
const stack = [root]
data.forEach(({id,...o})=>{
  if(id==='BP') {
    let x = {id,...o};
    (stack[0].children??=[]).push(x)
    stack.unshift(x)
  }
  else if(id==='EP') stack.shift()
  else (stack[0].children??=[]).push({id,...o})
})
console.log(root.children)

请注意,上述代码是JavaScript代码,用于处理数据对象。

英文:

I don't completely understand your question, but this answer might help you refine the question:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const data = [{&quot;id&quot;:&quot;BP&quot;,&quot;collapsed&quot;:false},{&quot;id&quot;:&quot;item&quot;},{&quot;id&quot;:&quot;item&quot;},{&quot;id&quot;:&quot;BP&quot;,&quot;collapsed&quot;:false},{&quot;id&quot;:&quot;item&quot;},{&quot;id&quot;:&quot;BP&quot;,&quot;collapsed&quot;:true},{&quot;id&quot;:&quot;item&quot;},{&quot;id&quot;:&quot;EP&quot;},{&quot;id&quot;:&quot;EP&quot;}]

const root = {}
const stack = [root]
data.forEach(({id,...o})=&gt;{
  if(id===&#39;BP&#39;) {
    let x = {id,...o};
    (stack[0].children??=[]).push(x)
    stack.unshift(x)
  }
  else if(id===&#39;EP&#39;) stack.shift()
  else (stack[0].children??=[]).push({id,...o})
})
console.log(root.children)

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年3月4日 01:35:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75630214.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定