将对象道具级别与可选道具进行比较

时间:2019-04-21 02:01:18

标签: javascript reactjs

这是我要求指导的问题类型,因为我不确定我要寻找的东西是否存在...

上下文: 我正在使用Firestore保存数据,并且正在构建一个可重复使用的自定义钩子(反应16.8),以便将数据保存到用户对象时使用。使用挂钩时,我将发送需要保存的道具,但是所有道具都是可选的。我想要做的基本上是设置整个Firestore对象 在客户端上应该是什么样的结构,然后比较props参数以确保它遵循约定原来的。

由于所有道具都是可选的,因此我仅尝试比较键的 level ,而不是值的相等性。原始骨架看起来像这样:

firestore obj

{
    name,
    email,
    bio {
        summary,
        array,
        photo
    },
    something,
    more,
    much
}

然后当我在应用程序中单击保存按钮时,我会将道具发送到可能看起来像这样的钩子(注意不完整):

{
    email: 'new@email.com',
    bio: {
        photo: 'url.com/new/photo'
    }
}

以上对象将通过测试。但是如果我通过这样的道具:

{
    photo: 'url.com/new/photo'
}

我的比较会检测到photo处于错误的级别,因为它应该是bio下的一个级别。

所以我的问题是,是否有一个可以帮助您的概念/程序包,或者我是否应该从头开始创建?

提前谢谢!

1 个答案:

答案 0 :(得分:1)

我过去也遇到过类似的问题,但没有找到任何解决方法。 因此,我为此编写了自己的函数,并且偶然的机会,我找到了这个旧代码。 它所做的比您的问题要多,因为他还测试元素是否在相同类型上。 这是:

const skeleton = { name:'',  email:'',  bio: { summary :'', array:[], photo:'' },
  something:'', more:'', much:'' };

var
  test1  = { email: 'new@email.com', bio: { photo: 'url.com/new/photo' } },
  test1b = { email: 'new@email.com', bio: { photo: 'url.com/new/photo', badThing: 25 } },
  test1c = { email: 'new@email.com', bio: [1,2,3] },
  test2  = { photo: 'url.com/new/photo'},
  testX  = 25;


console.log ('test 1 is conform ->'  , hasSamePlacedKeys(skeleton, test1 ));
console.log ('test 1b is conform ->' , hasSamePlacedKeys(skeleton, test1b ));
console.log ('test 1c is conform ->' , hasSamePlacedKeys(skeleton, test1c ));
console.log ('test 2 is conform ->'  , hasSamePlacedKeys(skeleton, test2 ));
console.log ('test X is conform ->'  , hasSamePlacedKeys(skeleton, testX ));



function hasSamePlacedKeys( refSkeleton, testObject )
{
  let
    objType = typeof(testObject),
    noErr   = ( objType==='object' && !Array.isArray(testObject) )
    ;

  for (let key in testObject )
  {
    noErr   = refSkeleton.hasOwnProperty(key);
    objType =  typeof(testObject[key]);

    if (noErr)
    { noErr = (objType === typeof(refSkeleton[key]) )  }

    if (noErr && objType==='object') {
      if ( Array.isArray(testObject[key]) )
      { noErr = Array.isArray(refSkeleton[key]) }
      else
      { noErr = hasSamePlacedKeys(refSkeleton[key], testObject[key] ) }
    }

    if (!noErr) break;
  }
  return noErr;
}