如何检查对象是否至少包含一个键,其值包含 JavaScript 中的子字符串?

Chr*_*kre 9 javascript string filtering substring object

我想编写一个函数来检查一个对象是否至少有一个包含子字符串的值。像这样(伪代码):

const userMatchesText = (text, user) => user.includes(text);
Run Code Online (Sandbox Code Playgroud)

我的对象的完整结构(

因此,对于像以下这样的用户:

const user = {
    id: '123abc',
    info: {
        age: 12,
        bio: 'This is my bio' 
    },
    social: {
        chatName: 'Chris',
        friends: ['friend1', 'other friend'],
        blocks: ['Creep']
    }
    //Etc. The objects I'm working with contain nested objects and arrays, etc.
}
Run Code Online (Sandbox Code Playgroud)

, userMatches('bi', user)应该返回,true因为子字符串 'bi' 在 bio: 'this is my bio' 中找到。userMatches('324d, user) 同样应该返回falseusermatches('blocks', user)但是,应该返回,false因为子字符串只能在其中一个键中找到,而不是在其中一个值中。

我正在处理的对象如下所示(Mongoose Schema):

{
    account  : {
        dateOfCreation : Number
    },
    social   : {
        chatName         : String,
        friends          : [ { type: String } ],
        blocks           : [ { type: String } ],
        sentRequests     : [ { type: String } ],
        recievedRequests : [ { type: String } ],
        threads          : [ { type: String } ]
    },
    info     : {
        age            : Number,
        bio            : String,
        displayName    : String,
        profilePicture : String,
        subjects       : {
            tutor   : [
                {
                    subject : String,
                    level   : String
                }
            ],
            student : [
                {
                    subject : String,
                    level   : String
                }
            ]
        }
    },
    facebook : {
        id         : String,
        firstName  : String,
        middleName : String,
        fullName   : String,
        lastName   : String
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,我发现的最好的方法是解构所有作为对象的字符串的键,然后使用mapand includes,就像下面的函数一样。

const doesUserMatchText = (user, text) => {
    const { social: { chatName }, info: { displayName }, facebook: { firstName, middleName, lastName } } = user;
    const possibleMatches = [ chatName, displayName, firstName, middleName, lastName ];
    let match = false;
    possibleMatches.map(possibleMatch => {
        if (possibleMatch.includes(text)) {
            return (match = true);
        }
    });
};
Run Code Online (Sandbox Code Playgroud)

然而,这真的很烦人(也可能效率极低),因为我正在使用的对象非常大。如果我可以调用userMatchesText(text, user)并获取布尔值,那就太好了。非常感谢!

另外,请注意我并没有解构所有字符串键。此功能的目的是根据搜索查询过滤用户,我认为让用户通过他们的个人资料、ID 等搜索其他用户可能没有太大意义,而是仅通过他们的各种“姓名” '。

CRi*_*ice 6

您可以使用递归函数来遍历整个对象。只要确保该对象没有任何循环引用...

const user = {
    id: '123abc',
    info: {
        age: 12,
        bio: 'This is my bio' 
    },
    social: {
        chatName: 'Chris',
        friends: ['friend1', 'other friend'],
        blocks: ['Creep']
    }
    //Etc. The objects I'm working with contain nested objects and arrays, etc.
};

function userMatchesText(text, user) {
    if (typeof user === "string") return user.includes(text);
    return Object.values(user).some(val => userMatchesText(text, val));
}

console.log(userMatchesText("bi", user));
console.log(userMatchesText("other fri", user));
console.log(userMatchesText("zzz", user));
Run Code Online (Sandbox Code Playgroud)