3
\$\begingroup\$

I have a nested object which I need to filter and sort.

  • I have a nested Object where some keys like app1 are nested inside another object.

  • I need to be able to filter out objects with the status of True.

  • I also need to be able to sort by date irrespective of how deep the object is nested.


This is the expected result.

[
  "appsd",
  {
    "appsf": {
      "date": "2017-01-05T17:13:53.956Z",
      "status": false
    }
  }
] [
  "appse",
  {
    "apps1": {
      "date": "2017-02-05T17:13:53.956Z",
      "status": false
    }
  }
] [
  "apps5",
  {
    "date": "2017-03-11T15:15:39.027Z",
    "status": false
  }
] [
  "apps4",
  {
    "date": "2017-04-11T15:15:39.027Z",
    "status": false
  }
] [
  "apps2",
  {
    "date": "2017-05-11T15:15:39.027Z",
    "status": false
  }
] [
  "appsf",
  {
    "apps1": {
      "date": "2017-07-05T17:13:53.956Z",
      "status": false
    }
  }
] [
  "appb",
  {
    "apps1": {
      "date": "2017-08-05T17:13:53.956Z",
      "status": false
    }
  }
] [
  "appsa",
  {
    "apps1": {
      "date": "2017-09-05T17:13:53.956Z",
      "status": false
    }
  }
]

From this original object

var object = {
  appsa: {
    apps1: {
      date: "2017-09-05T17:13:53.956Z",
      status: false
    }
  },
  appb: {
    apps1: {
      date: "2017-08-05T17:13:53.956Z",
      status: false
    }
  },
    appsf: {
    apps1: {
      date: "2017-07-05T17:13:53.956Z",
      status: false
    }
  },
  apps2: {
    date: "2017-05-11T15:15:39.027Z",
    status: false
  },

  apps3: {
    date: "2017-06-11T15:36:33.063Z",
    status: true
  },
  apps4: {
    date: "2017-04-11T15:15:39.027Z",
    status: false
  },
  apps5: {
    date: "2017-03-11T15:15:39.027Z",
    status: false
  },
   appse: {
    apps1: {
      date: "2017-02-05T17:13:53.956Z",
      status: false
    }
  },
   appsd: {
    appsf: {
      date: "2017-01-05T17:13:53.956Z",
      status: false
    }
  },
};

Concerns about my code.

  • recursive style.

  • pushing order and deeply nested object

  • am also not doing any recursion on the filter.

  • variable naming efficiency and clarity

var object = {
  appsa: {
    apps1: {
      date: "2017-09-05T17:13:53.956Z",
      status: false
    }
  },
  appb: {
    apps1: {
      date: "2017-08-05T17:13:53.956Z",
      status: false
    }
  },
  appsf: {
    apps1: {
      date: "2017-07-05T17:13:53.956Z",
      status: false
    }
  },
  apps2: {
    date: "2017-05-11T15:15:39.027Z",
    status: false
  },

  apps3: {
    date: "2017-06-11T15:36:33.063Z",
    status: true
  },
  apps4: {
    date: "2017-04-11T15:15:39.027Z",
    status: false
  },
  apps5: {
    date: "2017-03-11T15:15:39.027Z",
    status: false
  },
  appse: {
    apps1: {
      date: "2017-02-05T17:13:53.956Z",
      status: false
    }
  },
  appsd: {
    appsf: {
      date: "2017-01-05T17:13:53.956Z",
      status: false
    }
  },
};

let apps = Object.entries(object)
  .filter(([key, value]) => !value.status)
  .sort((val=> (a, b) => {
    let temp = [];
    let sortMatch = root => {
      if (root.date) {
        temp.push(root.date);
      }
      for (let key in root) {
        if (typeof root[key] === "object") {
          sortMatch(root[key]);
        }
      }
    };
    sortMatch({
      a: a,
      b: b
    });
    val['tempB'] = temp.pop();
    val['tempA'] = temp.pop();
    return val.tempA.localeCompare(val.tempB);
  })({}));

console.log(...apps);
.as-console-wrapper {
  max-height: 100% !important;
  top: 0;
}

\$\endgroup\$
2
\$\begingroup\$
  1. If you have control over the format of the object you're filtering and sorting, then you should definitely consider reformatting it into something more palatable.

  2. Using localeCompare() to sort Date objects seems funky. You can do something like this:

    return new Date(tempB).getTime() - new Date(tempA).getTime()
    
  3. If you don't know how deep the object is nested, then recursion is a pretty solid way to go. If you want to try a more hackish solution, you could also use JSON.stringify() and regex to extract the date fields from deeply nested objects (not suggested). Please provide more examples of valid objects to sort though, your code seems like it would break on certain instances.

\$\endgroup\$
  • \$\begingroup\$ added a larger sample and still works. ISO-8601 dates are formatted so they string compare correctly. \$\endgroup\$ – Rick Jul 13 '17 at 20:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.