How to check whether a value exists in a nested object recursively

Unable to create a fully recursive function that checks if a value exists in a nested object

tried Implementing the code in JavaScript(ES6+) but only managed to do it semi-recursive with a for loop to check the contents of key at a time

function contains(obj, value) {
  for (var key in obj) {
    if (typeof obj[key] === "object") {
      return contains(obj[key], value);
    }

    if (obj[key] === value) {
      return true;
    }
  }
  return false;
}

New contributor

Dvir Rozenblat is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

2

Your example is quite lacking… But I’ll try to help you with what’s available…

If you want to verify, and just verify, if an object has some value as one of its enumerable properties value, then you can do just this:

Object.values(Object(obj)).includes(val);

NOTE: Object.values() return an array of the enumerable properties values only.

If you want to verify all properties (including non-enumerable properties), then you could do something like this:

function Contains ( Subject, Value, Hidden = true, Prototype = true, Verifieds = [] )
{
   let Current = Object(Subject);
   
   if ( ! Array.isArray(Verifieds) )
   {
      Verifieds = [Verifieds];
   }
   
   do
   {
      // Adds every object in the prototype chain to the `Verifieds` parameter.
      Verifieds.push(Current);
      
      for ( const Property of ( Hidden ? Reflect.ownKeys(Current) : Object.keys(Current) ) )
      {
         // Is the `Value` in the shallowest level?
         if ( Object.is(Value, Current[Property]) )
         {
            return true;
         }
         
         // The `Value` nests other values?
         if ( ( Current[Property] !== null ) && ( typeof Current[Property] == 'object' ) )
         {
            // If the current property value was verified...
            if ( Verifieds.includes(Current[Property]) )
            {
               // ... then continue to the next property.
               continue;
            }
            
            else
            {
               // ... Else, add the current property to the `Verifieds` parameter.
               Verifieds.push(Current[Property]);
            }
            
            // If the current property value nested the `Value`...
            if ( Contains(Current[Property], Value, Hidden, Prototype, Verifieds) )
            {
               return true;
            }
         }
      }
      
      Current = Object.getPrototypeOf(Current);
      
      // Verify if `Value` is in the prototype chain.
      if ( Prototype && Object.is(Current, Value) )
      {
         return true;
      }
   }
   while ( Current !== null );
   
   return false;
}

// Simple object
var Obj1 = { AnyProperty: 3 };

console.log( 'Obj1 =', Obj1 );
console.log( '3?', Contains(Obj1, 3) ); // outputs: 3? true
console.log( '2?', Contains(Obj1, 2) ); // outputs: 2? false

// Simple object with non enumerable property
var Obj2 = { [ Symbol('Non Enumerable Property') ]: 5 };

console.log( 'Obj2 =', Obj2 );
console.log( '5?', Contains(Obj2, 5) ); // outputs: 5? true
console.log( '4?', Contains(Obj2, 4) ); // outputs: 4? false
console.log( '3?', Contains(Obj2, 3) ); // outputs: 3? false
console.log( '2?', Contains(Obj2, 2) ); // outputs: 2? false
// Obj2 didn't inherit Obj1 in the code above.

// But now Obj2 inherits Obj1.
Object.setPrototypeOf(Obj2, Obj1);

// Obj3 inherits Obj2 that inherits Obj1.
var Obj3 = Object.create(Obj2);

console.log( 'Obj3 =', Obj3 );
console.log( '5?', Contains(Obj3, 5) ); // outputs: 5? true
console.log( '4?', Contains(Obj3, 4) ); // outputs: 4? false
console.log( '3?', Contains(Obj3, 3) ); // outputs: 3? true
console.log( '2?', Contains(Obj3, 2) ); // outputs: 2? false

// Obj4 contains Obj1, Obj2 and itself.
var Obj4 = { Obj1, Obj2, get Self () { return Obj4; } };
// Note that here Obj2 inherits Obj1.

console.log( 'Obj4 =', Obj4 );
console.log( 'Obj1?', Contains(Obj4, Obj1) ); // outputs: Obj1? true
console.log( 'Obj2?', Contains(Obj4, Obj2) ); // outputs: Obj2? true
console.log( 'Obj3?', Contains(Obj4, Obj3) ); // outputs: Obj3? false
console.log( 'Obj4?', Contains(Obj4, Obj4) ); // outputs: Obj4? true
// Verifying the nested values...
console.log( '5?', Contains(Obj4, 5) ); // outputs: 5? true
console.log( '4?', Contains(Obj4, 4) ); // outputs: 4? false
console.log( '3?', Contains(Obj4, 3) ); // outputs: 3? true
console.log( '2?', Contains(Obj4, 2) ); // outputs: 2? false

// Whoops... Obj5 contains Obj3 that inherits Obj2 that inherits Obj1.
var Obj5 = { Obj3 };

console.log( 'Obj5 =', Obj5 );
console.log( 'Obj1?', Contains(Obj5, Obj1) ); // outputs: Obj1? true
console.log( 'Obj2?', Contains(Obj5, Obj2) ); // outputs: Obj2? true
console.log( 'Obj3?', Contains(Obj5, Obj3) ); // outputs: Obj3? true
console.log( 'Obj4?', Contains(Obj5, Obj4) ); // outputs: Obj4? false
// Verifying the nested values...
console.log( '5?', Contains(Obj5, 5) ); // outputs: 5? true
console.log( '4?', Contains(Obj5, 4) ); // outputs: 4? false
console.log( '3?', Contains(Obj5, 3) ); // outputs: 3? true
console.log( '2?', Contains(Obj5, 2) ); // outputs: 2? false
console.log( 'Excluding the hidden values...' );
console.log( 'Obj1?', Contains(Obj5, Obj1, false) ); // outputs: Obj1? true
console.log( 'Obj2?', Contains(Obj5, Obj2, false) ); // outputs: Obj2? true
console.log( 'Obj3?', Contains(Obj5, Obj3, false) ); // outputs: Obj3? true
console.log( 'Obj4?', Contains(Obj5, Obj4, false) ); // outputs: Obj4? false
console.log( '5?', Contains(Obj5, 5, false) ); // outputs: 5? false
console.log( '4?', Contains(Obj5, 4, false) ); // outputs: 4? false
console.log( '3?', Contains(Obj5, 3, false) ); // outputs: 3? true
console.log( '2?', Contains(Obj5, 2, false) ); // outputs: 2? false
console.log( 'And then excluding the the prototype chain...' );
console.log( 'Obj1?', Contains(Obj5, Obj1, false, false) ); // outputs: Obj1? false
console.log( 'Obj2?', Contains(Obj5, Obj2, false, false) ); // outputs: Obj2? false
console.log( 'Obj3?', Contains(Obj5, Obj3, false, false) ); // outputs: Obj3? true
console.log( 'Obj4?', Contains(Obj5, Obj4, false, false) ); // outputs: Obj4? false
console.log( '5?', Contains(Obj5, 5, false, false) ); // outputs: 5? false
console.log( '4?', Contains(Obj5, 4, false, false) ); // outputs: 4? false
console.log( '3?', Contains(Obj5, 3, false, false) ); // outputs: 3? true
console.log( '2?', Contains(Obj5, 2, false, false) ); // outputs: 2? false

NOTE: I added a Hidden parameter with default value of true. This means that if you not specify false as the third parameter it will verify all properties including those that are not enumerables. You can invert this behavior by changing the default to false.

NOTE: The Prototype parameter with the default value of true tells the function that if Value is a prototype of Subject or one of its nested values it must return true. This does not means that if you use false as this parameter value the function will not verify the prototype chain (it always does). See the Obj5 example for details.

NOTE: The Verifieds parameter is there to prevent infinite looping when Subject nests itself.

3

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật