编程语言
首页 > 编程语言> > javascript-搜索包含值的json对象键,然后将其取消设置

javascript-搜索包含值的json对象键,然后将其取消设置

作者:互联网

我正在寻找一种搜索JSON对象的方法,以检查它是否包含给定值,如果存在,则将其取消设置.

我的数据结构如下(并附有解释):

// Search within the 'seats' array for a given 'guestID', if it exists, unset it
tables = [
   {
      "_id":{
         $oid: "one"
      },
      "seats":[
         { "guestId":"01" },
         { "guestId":"02" },
         { "guestId":"03" }
      ]
   },
   {
      "_id":{
         $oid: "two"
      },
      "seats":[
         { "guestId":"11" },
         { "guestId":"12" },
         { "guestId":"13" }
      ]
   }
]

我正在为该项目使用下划线,并且尝试使用_.pluck(tables,’seats’)然后使用_.foreach,但是我不得不嵌套多个_.foreach语句来访问seats数组进行搜索,并且我不确定这是否是最佳做法.有没有我不知道的简便方法?

该数据是从mongolab REST API返回的.我应该在最初的XHR请求中执行此操作,而不是获取一个大对象然后尝试通过客户端对其进行解析吗?

如果这是一个SQL请求,我将能够执行诸如select table.seats之类的操作,其中guestId = XXX

解决方法:

过去,无论何时遇到这种情况,递归搜索功能始终是无价之宝…这是我所经历的一个(我通过添加remove方法对其进行了扩展):

function o ( target ) {
  /// if an instance of o has been created, then handle it
  if ( this instanceof o ) {
    /// O INSTANCE:
    /// an instance of o acts like a reference or pointer 
    /// to how the value it targets was reached.
    this.value = target;
    this.key = arguments[1];
    this.parent = arguments[2];
    this.toString = function(){ return 'o('+this.key+' = '+this.value+')';}
  }
  /// if no instance being created fall back to the 'scan object' code
  else {
    /// RECURSIVE CODE:
    /// the _ function is responsible for accepting the 
    /// attributeName and attributeValue search
    var _ = function ( key, value, modifier ) {
      var i, v, tar = ( modifier ? modifier.target : target ), items = [];
      /// if we are dealing with an o instance, handle slightly differently
      if ( tar instanceof o ) {
        for ( i in tar.value ) {
          /// check to see if our current key and value 
          /// match our search terms
          if ( _.test( i, (v=tar.value[i]), key, value ) ) {
            items.push(new o(v, i, tar));
          };
        };
      }
      /// if no o instance treat as a normal object or array
      else {
        for ( i in tar ) {
          if ( (v = tar[i]) ) {
            /// if we are an instance of o, recurse to actually 
            /// check the items within
            if ( v instanceof o ) {
              items = items.concat( _( key, value, {target:v} ) );
            }
            /// check to see if our current key and value match 
            /// our search terms
            else if ( _.test( i, v, key, value ) ) {
              items.push(new o(v, i, tar));
            };
          };
        };
      };
      /// if in modifier mode, don't rely on storing in scope, 
      /// return the calculated items instead
      if ( modifier ) {
        return items;
      }
      else {
        /// update what we are targeting
        target = items;
        /// return our underscore function
        return _;
      };
    };
    /// FUNCTION DECLARATIONS:
    /// a quick test to see if the key and value match (or either or)
    _.test = function ( i,v,key,value ) {
      var havekey = ( key !== null && key !== undefined ),
          haveval = ( value !== null && value !== undefined ),
          passkey = ( havekey && (i == key || key === '*') ),
          passval = ( haveval && (v == value || value === '*') );
      return ( havekey && haveval && passkey && passval ) || 
        ( havekey && !haveval && passkey ) || 
        ( haveval && !havekey && passval );
    };
    /// calculate the path needed to reach the object within the structure
    _.path = function () {
      var i = target.length, paths = [], path, cur, last;
      while ( i-- ) {
        cur = target[i]; path = [];
        do{ last = cur; if ( cur instanceof o ){ path.unshift( cur.key ); } }
          while( (cur = cur.parent) );
        paths.push(path.join('/'));
      };
      return ( paths.length == 1 ? paths[0] : paths );
    };
    /// remove the item we are targeting by stepping back 
    /// and deleting ourselves from the previous parent
    _.remove = function ( removeEntireObject ) {
      var i = target.length, paths, path, cur, last;
      while ( i-- ) {
        cur = target[i];
        /// remove the object that has the found attribute
        if ( removeEntireObject ) {
          if ( cur.parent.parent ) {
            cur.parent.parent.value[cur.parent.key] = null;
            delete cur.parent.parent.value[cur.parent.key];
          }
        }
        /// otherwise remove only the targeted attribute
        else {
          cur.parent.value[cur.key] = null;
          delete cur.parent.value[cur.key];
        }
      };
      return _;
    };
    /// a useful function for backwards navigation
    _.parent = function () {
      var i = target.length, cur, items = [], values = [];
      while ( i-- ) {
        cur = target[i];
        /// remove the object that has the found attribute
        if ( cur && cur.parent ) {
          /// store the values as we go so we can 
          /// spot and remove duplicated parents
          if ( values.indexOf(cur.parent.value) === -1 ) {
            items.push(cur.parent);
            values.push(cur.parent.value);
          }
        }
      };
      target = items;
      return _;
    }
    /// slimple debugging
    _.alert = function () {
      var i = target.length, cur;
      while ( i-- ) {
        cur = target[i];
        alert(cur);
      };
      return _;
    };
    return _;
  };
};

用法示例:

/// remove only the guestId object with a value '01'

o(tables)('*')('seats')('*')('guestId', '01').remove( true );

要么:

/// remove the 'guestIds' object in the first slot for either seat

o(tables)('*')('seats')(0)('guestId', '*').parent().remove();

要么:

/// remove all 'guestIds' from the first seat

o(tables)(0)('seats')('*')('guestId').parent().remove();

说明:

>您必须始终通过调用o(my_object_to_parse)开始.
>传递一个参数充当attributeName搜索.
>传递两个参数充当attributeName和attributeValue搜索.
> *用作简单的通配符,可用于处理基本数组.
> *可以用作attributeName或attributeValue.
>每个后续请求都将层次进一步移入结构.

我已经有一段时间没有使用此代码了,因此它可能不是100%无错误或最佳的.但是,它似乎适用于您的特定用例……并且它还可以处理我在测试时所扔的所有内容.用.remove()、. parent()、. path()和.alert()扩展更多的方法应该足够容易,并且最好添加一些错误检查.

标签:javascript,json,underscore-js,mlab
来源: https://codeday.me/bug/20191012/1902557.html