3

I have a sample object structure like below

Even though there are three types of addresses (address, employeeAddress, shippingAddress), they all represent the same data structure called address. From this object structure, I need to get all the addresses from the above structure.The object structure might be defined in using a JSON Schema format. Also the addresses need not be always as part of the same hierarchy. For example in the above, shippingAddress and employeeAddress are at different hierarchy. I tried with object's hasOwnProperty, but did not work the way as expected. Did not get much help from the filter method in lodash also. Is there an elegant way to achieve this?

{
  "user": {
    "firstName": "John",
    "lastName": "Steve",
    "address": {
      "houseNo": "24",
      "city": "CA",
      "country": {
        "code": "US",
        "name": "United States"
      }
    }
  },
  "employee": {
    "employeeID": "443434",
    "employeeName": "Steve",
    "employeeAddress": {
      "houseNo": "244",
      "city": "NJ",
      "country": {
        "code": "US",
        "name": "United States"
      }
    }
  },
  "assistant": {
    "assitantID": "443434",
    "employeeName": "Steve",
    "shippingDetails": {
      "shippingAddress": {
        "houseNo": "2444",
        "city": "LA",
        "country": {
          "code": "US",
          "name": "United States"
        }
      }
    }
  }
}
Apps
  • 3,284
  • 8
  • 48
  • 75

2 Answers2

2

You could use recursion for this and create a function that takes input data and schema object. Then on each level another function checks if the current object matches schema structure.

const data = {"user":{"firstName":"John","lastName":"Steve","address":{"houseNo":"24","city":"CA","country":{"code":"US","name":"United States"}}},"employee":{"employeeID":"443434","employeeName":"Steve","employeeAddress":{"houseNo":"244","city":"NJ","country":{"code":"US","name":"United States"}}},"assistant":{"assitantID":"443434","employeeName":"Steve","shippingDetails":{"shippingAddress":{"houseNo":"2444","city":"LA","country":{"code":"US","name":"United States"}}}}}

const schema = {
  houseNo: null,
  country: null,
  city: null
}

function match(o1, o2) {
  return Object.keys(o1).every(k => k in o2);
}

function get(data, schema) {
  return Object.keys(data).reduce((r, e) => {
    if (match(data[e], schema)) r.push(data[e]);
    else if (typeof data[e] == 'object') r.push(...get(data[e], schema));
    return r;
  }, [])
}

const result = get(data, schema);
console.log(result)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
0

Here is a plain JS version of one found here

var user = { "user": { "firstName": "John", "lastName": "Steve", "address": { "houseNo": "24", "city": "CA", "country": { "code": "US", "name": "United States" } } }, "employee": { "employeeID": "443434", "employeeName": "Steve", "employeeAddress": { "houseNo": "244", "city": "NJ", "country": { "code": "US", "name": "United States" } } }, "assistant": { "assitantID": "443434", "employeeName": "Steve", "shippingDetails": { "shippingAddress": { "houseNo": "2444", "city": "LA", "country": { "code": "US", "name": "United States" } } } } }

function findProp(obj, prop) {
  var result = {};
  function recursivelyFindProp(o, keyToBeFound) {
    Object.keys(o).forEach(function (key) {
      if (typeof o[key] === 'object') {
        if (key.toLowerCase().indexOf(keyToBeFound) !==-1) result[key]=o[key];
        recursivelyFindProp(o[key], keyToBeFound);
      } else {
        if (key.toLowerCase().indexOf(keyToBeFound) !==-1) result[key]=o[key];
      }
    });
  }
  recursivelyFindProp(obj, prop);
  return result;
}
console.log(
  findProp(user, "address")
)  
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
mplungjan
  • 169,008
  • 28
  • 173
  • 236