0

I am extracting some data out of an array of nested objects, using two reducees, and map, which is working at the moment, but it is a bit ugly. How can this be optimized?

function extractSchools(schools) {
  let schoolData = [];

  if (schools) {
    schoolData = schools.reduce(function(parentdata, chlrn) {
      let childrenlist = chlrn.children;
      let childrendata = [];

      if (childrenlist) {
        childrendata = childrenlist.reduce(function(addrsslist, school) {
          return addrsslist.concat(school.address.map(i => i.school));
        }, []);
      }

      return parentdata.concat(chlrn.parent, childrendata);
    }, []);
  }

  return {
    schoolData
  };
}

const schools = [{
    "parent": "Thomas Jefferson",
    "children": [{
        "address": [{
          "school": "School A"
        }]
      },
      {
        "address": [{
          "school": "School B"
        }]
      }
    ]
  },
  {
    "parent": "Jack Chan",
    "children": [{
      "address": [{
        "school": "School C"
      }]
    }]
  }
];


console.log(extractSchools(schools));

How can I optimize this function to get the same results? using one reduce instead of two... or some other optimal way of doing it.

2
  • Your code is fine, what is the concern with 2 reduces? Commented Mar 19, 2018 at 10:59
  • I don't see any problems with your code, I'd be more interested in the why of some of the choices in data format. A) Why the keys parent and children. Should they be name and addresses? Or is there more nesting going on? B) Why is the address an array and is the label nested in an object with a school property? I think the only way you can simplify the data conversion is by altering the data format to better meet your front-end requirements. Commented Mar 19, 2018 at 16:20

2 Answers 2

1

You can remove the if (childrenlist) { and use a pre-filter.

function extractSchools(schools) {
  let schoolData = [];

  if (schools) {
    schoolData = schools
      .filter(data => data.children)
      .reduce((parentdata, chlrn) => {
        const childrendata = chlrn.children.reduce(
          (addrsslist, school) =>
            addrsslist.concat(school.address.map(i => i.school)),
          []
        );
        return parentdata.concat(chlrn.parent, childrendata);
      }, []);
  }

  return { schoolData };
}

const schools = [
  {
    parent: "Thomas Jefferson",
    children: [
      {
        address: [
          {
            school: "School A"
          }
        ]
      },
      {
        address: [
          {
            school: "School B"
          }
        ]
      }
    ]
  },
  {
    parent: "Jack Chan",
    children: [
      {
        address: [
          {
            school: "School C"
          }
        ]
      }
    ]
  }
];

console.log(extractSchools(schools));
Sign up to request clarification or add additional context in comments.

2 Comments

can you provide a full answer ?
I hope it's helps :)
1

Try this, the result is little different than what you are expecting, but this will be a more generic way where you will have addresses with respect to school.

schools.map(p => {
    return {[p.parent]: p.children.map(c => c.address.map(add => add.school))}
})


[
  {
    "Thomas Jefferson": [
      [
        "School A"
      ],
      [
        "School B"
      ]
    ]
  },
  {
    "Jack Chan": [
      [
        "School C"
      ]
    ]
  }
]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.