Get property value from object tree in a recursive way Consider the following structure,

let condition = { and: [ { id: 3 }, { pageId: '1' } ] }


I want to get the id property value in a recursive way, it can be also nested inside other conditions.

for example the structure could be like that

let condition = {or: [{ and: [ { id: 3 }, { pageId: '1' } ] }, {age: 10}]}


I ended using this but I don't like the final syntax 

  function getIdConditionValue(cond) {
    if (isArray(cond.and)) {
      return map(cond.and, getIdConditionValue);
    } else if (isArray(cond.or)) {
      return map(cond.or, getIdConditionValue);
    }
    if (cond.id) return cond.id;
  }

const id = getIdConditionValue(condition).filter(x =&gt; x)[0];


It is working, but I would like to remove .filter(x =&gt; x)[0] part from the calling function, which I added because the returned value would be like this [1, undefined].
Given the map() function used at the question having the same signature as jQuery.map() function used at the question, in order to avoid chaining .filter() to get the value at index 0 of the returned, you can use destructuring to assign id to the value at index 0 of the array returned from the function.



function getIdConditionValue(cond) {
  if (Array.isArray(cond.and)) {
    return $.map(cond.and, getIdConditionValue);
  } else if (Array.isArray(cond.or)) {
    return $.map(cond.or, getIdConditionValue);
  }
  if (cond.id) return cond.id;
}

var condition = {
  or: [{
    and: [{
      id: 3
    }, {
      pageId: '1'
    }]
  }, {
    age: 10
  }]
}


const [id] = getIdConditionValue(condition);

console.log(id);
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"&gt;
&lt;/script&gt;




For Loash and Underscore signatures of map() signature (each library's _.map() returns an array having two elements, the fist is the expected result, the second undefined)  you can use 

const [[id]] = getIdConditionValue(condition);




For an alternative recursive solution you can create a function that accepts an object and a property name for parameter, utilizes the recursive replacer function of JSON.stringify() and JSON.parse(). If the property name is found during recursive iteration of property names of the object passed, a parameter of an immediately invoked arrow function declared as undefined is set to the property value, else undefined is returned from the function.



const condition1 = {and: [{id:3}, {pageId:'1'}]};
const condition2 = {or: [{and: [{id: 3}, {pageId: '1'}]}, {age: 10 }]};
const condition3 = {and:[,,]};
const condition4 = {and:{or:[]}};
const condition5 = {or:[{or:[{id:1}]}]};

const getObjectPropertyValue = (o, prop) =&gt; (result =&gt;
  (JSON[typeof o === 'string' ? 'parse' : 'stringify'](o, (key, value) =&gt; 
    key == prop ? (result = value) : value), result))(void 0);

let prop = 'id';

const id1 = getObjectPropertyValue(condition1, prop);

console.log(id1);

let condition2json = JSON.stringify(condition2);

const id2 = getObjectPropertyValue(condition2json, prop);

console.log(id2);

const id3 = getObjectPropertyValue(condition3, prop);

console.log(id3); // `undefined`

const id4 = getObjectPropertyValue(condition4, prop);

console.log(id4); // `undefined`

const id5 = getObjectPropertyValue(condition5, prop);

console.log(id5);