2
\$\begingroup\$

I use the following code to find if there is duplicate value in property path:

return new Promise((resolve, reject) => {
            var data = [];
            Parser.parse()
             //configObj is the value from the screen shot
                .then((configObj) => {
                    configObj.forEach((providers) => {
                        _.each(providers, (provider) => {
                            _.each(provider, (entry) => {
                                for (var prop in entry) {
                                    if (_inArray(entry[prop].path, data)) {
                                        return reject(new Error(`Duplicate path ${entry[prop].path}`));
                                    }
                                    data.push(entry[prop].path);
                                }
                            })
                        })
                    })
                    resolve("validObject");
                }, err => {
                    reject(err);
                });

For example, this is the object configObj and as you can see I need to find duplicate in object 'replace' and object 'save' for the value in field 'path'; if they have the same value, it rejects with error; otherwise it resolves the promise. Is there is more elegant way to write it?

enter image description here

In this example, the path is different (test2 & command1) but it can also be the same.

update

[
  {
    "providers": [
      {
        "replace": {
          "path": "command1",
          "function": "updateResources",
          "method": "post"
        },
        "save": {
          "path": "test2",
          "function": "updateResources",
          "method": "post"
        }
      }
    ]
  }
]
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

A very fun question, which took way too much time to analyze ;) It would have helped tremendously if you could have given a sample JSON instead of a screenshot.

Regardless, if you are using lodash anyway, you might as well leverage it all the way. By trying the different functions provided by lodash you start thinking differently about data structures.

The code I proposes flattens the array you are getting so that you just have a list of entries. Then it gets the properties from the entries, which it flattens again to have a nice searchable array. Then it counts the paths and checks for dupes, then it checks whether any dupe was found.

Instead of having the full Promise code, I will provide the essence:

var configObj = [{
  "providers": [{
    "replace": {
      "path": "command1",
      "function": "updateResources",
      "method": "post"
    },
    "save": {
      "path": "test2",
      "function": "updateResources",
      "method": "post"
    }
  }]
}];

var providers = _.values(configObj);
var entries = _.flatMapDeep(providers, _.values);
var props = _.flatMapDeep(entries, _.values);
var counts = _.countBy(props, 'path');
var dupe = _.findKey(counts, count => {
  return count > 1;
});
console.log(dupe ? dupe : 'No dupe found');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>

The nice thing about this approach is that if you wanted to change the functionality and log all the dupes at once, you could.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you very much for this informative answer , I've tried it and it seems that this is not working ... As you request this is the json file , I just parse it 'Parser.parse()' and do the logic , can you take a look please \$\endgroup\$
    – Rayn D
    Commented Jul 31, 2016 at 6:52
  • \$\begingroup\$ @RaynD Awesome, updated my answer based on the JSON. \$\endgroup\$
    – konijn
    Commented Jul 31, 2016 at 14:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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