master00
master00

Reputation: 137

Retrieve nested object by key

What would be the most efficient way (with performance in mind, assuming object may be large) to retrieve a nested object by it's key (itemID) within the following object?

Obviously, I can access the object by first referencing each of the parents (searchResults.page2.item3) but how can I retrieve item3 from searchResults using only the itemID assuming I don't know what page it's on?

var searchResults = {

    page1 : {

        item1 : {},
        item2 : {}      

    },

    page2 : {

        item3 : {},
        item4 : {}  
    }

}

Upvotes: 1

Views: 96

Answers (3)

mike510a
mike510a

Reputation: 2168

Use a recursive function to just check the entire object until it finds item3

var searchResults = {
  page1: {
    item1: {
      id: 1
    },
    item2: {
      id: 2
    }
  },
  page2: {
    item3: {
      id: 3
    },
    item4: {
      id: 4
    }
  }
}

/* start the operation */
recurse_object(searchResults, 0);

function recurse_object(obj, curIdx) {
  /* create array with all keys for an object */
  var keys = Object.keys(obj);


  /* check if we have gone through all of the object's keys */
  if (curIdx < keys.length) {

    /* if not, grab the key associated with curIdx */
    var keyVal = keys[curIdx];

    if (keyVal == 'item3') {
      console.log("FOUND ITEM3 ID! " + obj.item3.id);
    } else {
      /* check if the current item has any sub-keys to check  */
      if (Object.keys(obj[keyVal]).length > 0) {


        /* check the any keys that exist in a particular key */
        recurse_object(obj[keyVal], 0);
      }
      /* now increase the index to check for the next key on object */
      curIdx++;
      recurse_object(obj, curIdx);
    }
  }

}


EDIT:

uncommented version with multiple input objects containing item3 as well as additional levels of nesting

var searchResults = {
  page1: {
    item1: {
      id: 1
    },
    item2: {
      id: 2
    }
  },
  page2: {
    item3: {
      id: 3
    },
    item4: {
      id: 4
    }
  },
  page20: {
    subPage1: {
      item3: {
        id: 6
      }
    },
    item5: {
      subItem2: {
        deepItem1: {
          item3: {
            id: 10
          }
        }
      }
    }
  }
}


recurse_object(searchResults, 0);

function recurse_object(obj, curIdx) {

  var keys = Object.keys(obj);



  if (curIdx < keys.length) {


    var keyVal = keys[curIdx];

    if (keyVal == 'item3') {
      console.log("FOUND ITEM3 ID! " + obj.item3.id);
    } else {

      if (Object.keys(obj[keyVal]).length > 0) {



        recurse_object(obj[keyVal], 0);
      }

      curIdx++;
      recurse_object(obj, curIdx);
    }
  }

}

Upvotes: 1

HenryDev
HenryDev

Reputation: 4953

Simply loop through your object. Here's a working solution. Hope it helps!

var searchResults = {
        page1 : {

            item1 : {},
            item2 : {}

        },
        page2 : {

            item3 : { id: 3},
            item4 : {}
        }
    }

    for(var i in searchResults){
        var pageNumber = searchResults[i];
        for(var j in pageNumber){
        var deeperProperty = pageNumber[j];
            if(deeperProperty.hasOwnProperty("id") && deeperProperty.id === 3){
                console.log(deeperProperty);
            }
        }
    }

Upvotes: 1

Ken
Ken

Reputation: 466

This does not seem efficient in the slightest, but it does what you are asking for as far as "can I retrieve item3 from searchResults using only the itemID assuming I don't know what page it's on?" goes.

var searchResults = {
  page1: {
    item1: { id: 1 },
    item2: { id: 2 }
  },
  page2: {
    item3: { id: 3 },
    item4: { id: 4 }
  }
}

var innerObjects = Object
.keys(searchResults)
  .map(
    function(key, index) {
      return Object
        .keys(searchResults[key])
          .map(
            function(innerKey, index) {
              return searchResults[key][innerKey];
            }
          );
    });
//console.log(innerObjects);
var flattenedArray = [].concat.apply([], innerObjects);
//console.log(flattenedArray);
var idYoureLookingFor = 3;
var objectYouWant = flattenedArray.filter(function(obj) { return obj.id == idYoureLookingFor; });
console.log(objectYouWant);

Upvotes: 0

Related Questions