【问题标题】:Replacing nested loop in JavaScript替换 JavaScript 中的嵌套循环
【发布时间】:2021-09-05 21:50:20
【问题描述】:

我有这样的对象数组

let data = [
    {
        "id": 1,
        "name": "Sam",
        "father": true,
        "group": "orange"
    },
    {
        "id": 2,
        "name": "Alex",
        "father": true,
        "group": "red"
    },
    {
        "id": 3,
        "name": "Rock",
        "father": true,
        "group": "blue"
    },
    {
        "id": 4,
        "name": "Liam",
        "father": false,
        "group": "red"
    },
    {
        "id": 5,
        "name": "Noah",
        "father": false,
        "group": "red"
    },
    {
        "id": 6,
        "name": "Oliver",
        "father": false,
        "group": "orange"
    },
    {
        "id": 7,
        "name": "Sara",
        "father": false,
        "group": "blue"
    },
    {
        "id": 8,
        "name": "Max",
        "father": false,
        "group": "red",

    }
]; 

我想对它进行排序,以便每个父亲都将他的孩子作为一个名为“成员”的键,它是父亲对象内的一个对象数组。 孩子的颜色必须与父亲的颜色相同。 所以例如输出应该是这样的:

     {
        "id": 1,
        "name": "Sam",
        "father": true,
        "group": "orange"
        "member":[
        {
            "id": 6,
            "name": "Oliver",
            "father": false,
            "group": "orange"
        }];


     {
            "id": 2,
            "name": "Alex",
            "father": true,
            "group": "red"
            "member":[
   {
        "id": 4,
        "name": "Liam",
        "father": false,
        "group": "red"
    },
    {
        "id": 5,
        "name": "Noah",
        "father": false,
        "group": "red"
    },
    {
        "id": 8,
        "name": "Max",
        "father": false,
        "group": "red",

    }
];

等等.. 我让它工作了,但我使用了嵌套循环, 这是我的代码:

function sorting(data) {
    //loop in all objects and find me all fathers
    data.forEach(fatherObjects => { 
        if (fatherObjects.father) {
            var member = [];
            //loop in all children objects and find me all children that has the same father color
            data.forEach(childrenObjects => {
                if (!childrenObjects.father && childrenObjects.group === fatherObjects.group) {
                    //add children objects to 'member' array
                    member.push(childrenObjects)
                }
            });
            //add 'member array vlaues to the member key inside father objects'
            fatherObjects["member"] = member;
            console.log(fatherObjects);
        }
    });
}
sorting(data);

这是可行的,但是由于两个嵌套循环,所有这些都运行得很慢 我怎样才能用更有效且不那么难以理解的东西来代替它。

【问题讨论】:

  • "这运行太慢了" 你真的测量过性能吗?现代浏览器中的 JS 可以每秒迭代大约 十亿 次的简单循环,我怀疑这段代码不是瓶颈。
  • 什么是孩子的父亲?即,如果它只是group,那么它是第一次找到成为父亲的项目吗?
  • @Jamiec 。父键必须为真,之后具有同一父组的每个对象都必须跟随他。从技术上讲,现在孩子有多个父亲,如果您在排序之前查看数据,您会发现父亲总是在孩子之前,我尝试使用这些但我没有弄明白。
  • @Teemu 我没有;但我认为有一种更好的方法可以使用,而不是每次循环整个数组 2 次。

标签: javascript arrays json sorting


【解决方案1】:

可以使用reduce 在单个循环中完成,基本上按group 属性和Object.values 分组以获得所需的结果

const result = Object.values(data.reduce((acc, i) => {
  if (!acc[i.group]) {
    acc[i.group] = {
      ...i,
      member: []
    }
  } else {
    acc[i.group].member.push(i);
  }
  return acc;
}, {}));

活生生的例子:

let data = [{
    "id": 1,
    "name": "Sam",
    "father": true,
    "group": "orange"
  },
  {
    "id": 2,
    "name": "Alex",
    "father": true,
    "group": "red"
  },
  {
    "id": 3,
    "name": "Rock",
    "father": true,
    "group": "blue"
  },
  {
    "id": 4,
    "name": "Liam",
    "father": false,
    "group": "red"
  },
  {
    "id": 5,
    "name": "Noah",
    "father": false,
    "group": "red"
  },
  {
    "id": 6,
    "name": "Oliver",
    "father": false,
    "group": "orange"
  },
  {
    "id": 7,
    "name": "Sara",
    "father": false,
    "group": "blue"
  },
  {
    "id": 8,
    "name": "Max",
    "father": false,
    "group": "red",

  }
];

const result = Object.values(data.reduce((acc, i) => {
  if (!acc[i.group]) {
    acc[i.group] = {
      ...i,
      member: []
    }
  } else {
    acc[i.group].member.push(i);
  }
  return acc;
}, {}));

console.log(result);

【讨论】:

  • @MrXQ 我不确定它是否完全符合您的预期 - 我没有注意到 father 属性
  • @Jmaiec 确实如此。但是我需要一些时间来了解您的解决方案,语法看起来对我来说是有线的,我是 JavaScript 新手
【解决方案2】:
function sorting(data) {
  var newFathersArray=[];
    data.forEach(fatherObjects => {
           if( fatherObjects.father ) {
             newFathersArray.push({
               ...fatherObjects,
               members:[]
             });
           }
    });
    data.forEach(fatherObject => {
       if( !fatherObject.father ) {
         newFathersArray.filter(f=>f.group===fatherObject.group)[0].members.push(fatherObject)
       }
    })

  return newFathersArray;
}
sorting(data);

【讨论】:

    猜你喜欢
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 2016-07-14
    • 2019-06-06
    • 2018-08-06
    • 2020-06-03
    相关资源
    最近更新 更多