繁体   English   中英

Javascript比较单个对象数组中的结果,如果值在同一对象数组中匹配,则追加

[英]Javascript compare results in a single object array and append if a value matches within the same object array

我希望尝试将数组连接到基本文件夹层次结构。

在我下面的示例中,“级别 1”是最低级别,此级别没有子文件夹。 “其他级别”将在“顶级”下有许多不同的文件夹

我有数据的数组如下:

[{ id: "Top Level", outerpath: "test plan", innerpath: "Regression" },
 { id: "other level", outerpath: "Regression", innerpath: "area 1" },
 { id: "Level 1", outerpath: "area 1", innerpath: "Subarea 1" },
 { id: "Level 1", outerpath: "area 1", innerpath: "Subarea 2" },
 { id: "Level 1", outerpath: "Regression", innerpath: "area 2" }]

现在我需要对象数组中数据的串联结果如下所示:

test plan/Regression/area 1/Subarea 1
test plan/Regression/area 1/Subarea 2
test plan/Regression/area 2

但是,我不知道如何开始。 也许它沿着通过匹配“innerpath”和“outpath”值的数组的循环线,然后将完成的数据推送到另一个数组?

任何想法都会非常有用。

更新:

为了扩展我的问题,数组是动态的,根据 API 的结果,它可能像这个数组

[{ id: "Top Level", outerpath: "test plan", innerpath: "Regression" }
{ id: "other level", outerpath: "Regression", innerpath: "area 1" }
{ id: "Level 1", outerpath: "area 1", innerpath: "Subarea 1" }
{ id: "other level", outerpath: "area 1", innerpath: "Subarea 2" }
{ id: "Level 1", outerpath: "Regression", innerpath: "area 2" }
{ id: "Top Level", outerpath: "test plan", innerpath: "other testing" }
{ id: "Level 1", outerpath: "other testing", innerpath: "other testing area 1" }
{ id: "other level", outerpath: "other testing", innerpath: "other testing area 2" }
{ id: "Level 1", outerpath: "other testing area 2", innerpath: "other testing subarea 1" }
{ id: "Level 1", outerpath: "Subarea 2", innerpath: "SubSubArea 1" }]

因此,不会只有一个顶级,它可以是多个顶级,因为文件夹“测试计划”将有多个文件夹,其中一些文件夹有自己的子文件夹。

在此处输入图片说明

我从 API 调用的回调中整理数据的代码在这里:

let testSuiteData = res;
           testSuiteData.value.forEach(async testSuiteItem => {
                  console.log(testSuiteItem);
    
                  if(!testSuiteItem.hasChildren === true) // Level 1
                  {
                      console.log(testSuiteItem.parentSuite.name + '/' + testSuiteItem.name)
                      folderHierarchy.path.push({
                          id: 'Level 1',
                          outerpath: testSuiteItem.parentSuite.name,
                          innerpath: testSuiteItem.name
                      })
                            
                  }
                  else if(testSuiteItem.hasChildren === true ) // other levels
                  {
                      if(testSuiteItem.parentSuite.name === testSuiteItem.plan.name) // Top Level
                      {
                          console.log(testSuiteItem.parentSuite.name + '/' + testSuiteItem.name)
                          folderHierarchy.path.push({
                              id: 'Top Level',
                              outerpath: testSuiteItem.parentSuite.name,
                              innerpath: testSuiteItem.name
                          })
                      }
                      else{ // Other Levels
                          console.log(testSuiteItem.parentSuite.name + '/' + testSuiteItem.name)
                          folderHierarchy.path.push({
                              id: 'other level',
                              outerpath: testSuiteItem.parentSuite.name,
                              innerpath: testSuiteItem.name
                          })
                      }
                  }
    
                        
                  console.log(folderHierarchy.path);

你可以做这样的事情

 const array = [{ id: "Top Level", outerpath: "test plan", innerpath: "Regression" }, { id: "other level", outerpath: "Regression", innerpath: "area 1" }, { id: "Level 1", outerpath: "area 1", innerpath: "Subarea 1" }, { id: "Level 1", outerpath: "area 1", innerpath: "Subarea 2" }, { id: "Level 1", outerpath: "Regression", innerpath: "area 2" }] const obj = {}; // a map of all our paths const topLevel = array.splice(0, 1)[0]; // removing the top level from array as it is not needed, and for further reference const base = `${topLevel.outerpath}/${topLevel.innerpath}`; // creating our default path, which we will use as a reference later for (let i = 0; i < array.length; i++) { const path = array[i].outerpath.split(' '); // creating a unique key for our map const key = path[1] ? path[1] : path[0]; if (!obj[key]) obj[key] = []; if (path[0] == 'area') obj[key].push(`${base}/${array[i].outerpath}/${array[i].innerpath}`); else if (path[0] == 'Regression') obj[key].push(`${base}/${array[i].innerpath}`) } console.log(obj);

我的方法分步骤:

  1. 找到第一个元素
  2. 找到这个元素的孩子
  3. 检查子元素的子元素
  4. 重复步骤 3 直到你有整棵树
  5. 压扁你的树

尝试自己做,然后才检查此示例以了解如何实现。

 class TreeList { tree = null; isTopLevel = (level) => { let topLevel = true; this.data.map(lv => { if (lv.innerPath === level.outerPath) { topLevel = false; } }); return topLevel; } createTree = (data) => { this.data = data; data.map(level => { if (this.isTopLevel(level)) { this.tree = level; } }); if (this.tree === null) { console.error('Couldn\\'t find top level.'); return; } this.tree = this.findChildLevels(this.tree); return this.flattenObject(this.tree); } findChildLevels = (level) => { this.data.map(lv => { if (lv.outerPath === level.innerPath) { if (level?.children === null || level?.children === undefined) { level.children = []; } level.children.push(this.findChildLevels(lv)); } }); return level; } flattenObject = (level) => { let currentPath = level.outerPath; let list = []; if (level?.children !== undefined && level?.children !== null) { level.children.map(child => { this.flattenChildren(list, currentPath, child); }); } else { list = [currentPath]; } return list } flattenChildren = (list, currentPath, level) => { if (level?.children !== undefined && level?.children !== null) { // currentPath += `/${level.outerPath}`; currentPath += '/' + level.outerPath; level.children.map(child => { this.flattenChildren(list, currentPath, child) }); } else { // list.push(`${currentPath}/${level.outerPath}/${level.innerPath}`); list.push(currentPath + '/' + level.outerPath + '/' + level.innerPath); } return list; } } const tl = new TreeList() const list = tl.createTree([ {id: "Top Level", outerPath: "test plan", innerPath: "Regression"}, {id: "other level", outerPath: "Regression", innerPath: "area 1"}, {id: "Level 1", outerPath: "area 1", innerPath: "Subarea 1"}, {id: "Level 1", outerPath: "area 1", innerPath: "Subarea 2"}, {id: "Level 1", outerPath: "Regression", innerPath: "area 2"} ]); list.map(item => { console.log(item); });

我认为我们可以通过首先创建一个所有唯一的innerpath值的列表来进一步简化它,这些值也不会显示为outerpath值,然后从每个值向后遍历。

下面是使用最新的动态对象数组时的样子:

我从你的原始数据中排除了id属性值,因为它似乎没有在任何地方使用,只是为了保持这个例子简洁,但你当然可以在你的最终版本中添加它。

 const data = [ { outerpath: "test plan", innerpath: "Regression" }, { outerpath: "Regression", innerpath: "area 1" }, { outerpath: "area 1", innerpath: "Subarea 1" }, { outerpath: "area 1", innerpath: "Subarea 2" }, { outerpath: "Regression", innerpath: "area 2" }, { outerpath: "test plan", innerpath: "other testing" }, { outerpath: "other testing", innerpath: "other testing area 1" }, { outerpath: "other testing", innerpath: "other testing area 2" }, { outerpath: "other testing area 2", innerpath: "other testing subarea 1" }, { outerpath: "Subarea 2", innerpath: "SubSubArea 1" } ]; const outerpaths = data.map(({ outerpath }) => outerpath), innerpaths = data.map(({ innerpath }) => innerpath).filter(innerpath => !outerpaths.includes(innerpath)); const concatenated = innerpaths.map(innerpath => { let obj = data.find(obj => obj.innerpath === innerpath), str = obj.outerpath + '/' + innerpath, i = 0; do { obj = data.find(({ innerpath }) => obj.outerpath === innerpath); if (obj) str = obj.outerpath + '/' + str; i++; } while (i < 20 && obj) return str; }); console.log(concatenated.join('\\n'));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM