提问者:小点点

使用递归函数向数组动态添加新维度


我有一个像这样的数组:

0: "SuSPENSE"
1: "Subcontractor Expense"
2: "Data Entry"
3: "Design"
4: "Programming"
5: "Subcontractor Expense - Other"
6: "Total Subcontractor Expense"
7: "Technology-Communication"
8: "Licenses"
9: "Domain Hosting Fee"
10: "Internet"
11: "Internet Servers"
12: "Internet - Other"
13: "Total Internet"
14: "Telephone"
15: "Call Center"
16: "Cellular Phones"
17: "Fax"
18: "Telephone - Other"
19: "Total Telephone"
20: "Hardware/Software"
21: "Computer Software"
22: "Hardware/Software - Other"
23: "Total Hardware/Software"
24: "Technology-Communication - Other"
25: "Total Technology-Communication"

这是类别和子类别的列表。 例如,“分包商费用”是一个子类别,以“分包商费用总额”结尾。 “internet”“total internet”相同。 模板总是相同的,category以“(name)”开头,以“total(name)”结尾。 但是每个类别可以有很多级别的子类别,就像一棵树。 我试图使用递归函数将这个数组解析为类似JSON的数组或多维数组,但我从来不知道最大深度是多少。 我尝试使用js执行以下操作:

var parsedArray = [];
var items = getLineItems("Expense", "Total Expense"); //This is a function to return the mentioned array
var newArray = parseArray(items, "Expense");

function parseArray(items, category){
    var lineItems = [];
    for(var i = 0; i < items.length; i++){
        var inArray = $.inArray("Total " + items[i], items);
        if(inArray !== -1){
            parseArray(getLineItems(items[i], "Total " + items[i]), items[i]);
        }
        else {
            lineItems.push(items[i]);
        }
    }
    parsedArray[category] = lineItems;
}

但是这个递归函数永远不会深入到2级以上。 有可能生成这样的东西吗?

"SuSPENSE"
"Subcontractor Expense"
    "Data Entry"
    "Design"
    "Programming"
"Subcontractor Expense - Other"
"Technology-Communication"
    "Licenses"
    "Domain Hosting Fee"
    "Internet"
        "Internet Servers"
        "Internet - Other"
    "Telephone"
        "Call Center"
        "Cellular Phones"
        "Fax"
        "Telephone - Other"
    "Hardware/Software"
        "Computer Software"
        "Hardware/Software - Other"
    "Technology-Communication - Other"

共2个答案

匿名用户

您可以通过检查当前元素是否具有以单词total开头,然后以当前元素的文本继续的相应元素来完成此操作,如果是,则递增级别。 当当前元素以word total开头时,则递减级别。

null

const data = {"0":"SuSPENSE","1":"Subcontractor Expense","2":"Data Entry","3":"Design","4":"Programming","5":"Subcontractor Expense - Other","6":"Total Subcontractor Expense","7":"Technology-Communication","8":"Licenses","9":"Domain Hosting Fee","10":"Internet","11":"Internet Servers","12":"Internet - Other","13":"Total Internet","14":"Telephone","15":"Call Center","16":"Cellular Phones","17":"Fax","18":"Telephone - Other","19":"Total Telephone","20":"Hardware/Software","21":"Computer Software","22":"Hardware/Software - Other","23":"Total Hardware/Software","24":"Technology-Communication - Other","25":"Total Technology-Communication"}

function toNested(data) {
  const result = [];
  const levels = [result]
  let level = 0;

  const checkChildren = (string, data) => {
    return data.some(e => e === `Total ${string}`)
  }

  data.forEach((e, i) => {
    const object = { name: e, children: []}
    levels[level + 1] = object.children;

    if (e.startsWith('Total')) level--;
    else levels[level].push(object);

    if (checkChildren(e, data.slice(i))) level++;
  })

  return result;
}

const result = toNested(Object.values(data));
console.log(result)

匿名用户

我还在猜测你的输出格式。 下面是一个递归解决方案,它给出了我在评论中询问的格式:

[
    {name: "SuSPENSE"},
    {name: "Subcontractor Expense", children: [
        {name: "Data Entry"},
        {name: "Design"},
        {name: "Programming"},
        {name: "Subcontractor Expense - Other"}
    ]},
    {name: "Technology-Communication", children: [
       //...
    ]}
]

null

const restructure = (
  [s = undefined, ...ss], 
  index = s == undefined ? -1 : ss .indexOf ('Total ' + s)
) => 
  s == undefined
    ? []
    : index > -1
      ? [
          {name: s, children: restructure (ss .slice (0, index))}, 
          ... restructure (ss .slice (index + 1))
        ]
      : [{name: s}, ... restructure (ss)]

const data = ["SuSPENSE", "Subcontractor Expense", "Data Entry", "Design", "Programming", "Subcontractor Expense - Other", "Total Subcontractor Expense", "Technology-Communication", "Licenses", "Domain Hosting Fee", "Internet", "Internet Servers", "Internet - Other", "Total Internet", "Telephone", "Call Center", "Cellular Phones", "Fax", "Telephone - Other", "Total Telephone", "Hardware/Software", "Computer Software", "Hardware/Software - Other", "Total Hardware/Software", "Technology-Communication - Other", "Total Technology-Communication"]

console .log (
  restructure (data)
)
.as-console-wrapper {min-height: 100% !important; top: 0}