Search code examples
javascriptlodashgraphql

How to check for array values in another array with lodash


My query filter

export const resolvers = {
    Query: {
        allItems: (_, { value }) => getAllLinks()
            .then(result => filter(result, val => val.custom_attributes
                .find(customVal =>
                    customVal.attribute_code === 'category_ids' && isEqual(customVal.value, value)
                )
                )),
    },

My schema

const typeDefs = `
    type Item  {
        id: ID!
        name: String
        price: Float
        custom_attributes: [CUSTOM_ATTRIBUTES]
    }

    union CUSTOM_ATTRIBUTES = CustomString | CustomArray 

   type CustomString {
    attribute_code: String
    value: String
  }

  type CustomArray {
    attribute_code: String
    value: [String]

  } 

  type Query {
    allItems(value : [String]): [Item]!

  }
`; 

For now (as I think) my filter works as AND condition in mysql.
For example, I have 3 fields
First

{
 value: ["3", "5"]
}

Second

{
 value: ["3", "5", "7"]
}

Third

{
 value: ["3"]
}

And my variable in argument is ["3"] Because I'm using isEqual function it will return only third field. That is incorrect, because ["3"] is in all three fields. Is there another function from lodash that can fix this little issue?


Solution

  • There are two different solutions, depending on what you want to achieve.

    For the simple case where the value array always contains 1 element, both options will work.

    I'll use this argument to show the difference: ["3", "7"]

    Option1: Field must contain any value

    If you expect to get all 3 fields because at least one item in the array ("3" in this case) is found in the variable and in customVal.value then you should use lodash's intersection and check if the result is not an empty array. Something like:

    intersection(customVal.value, value).length > 0
    

    This expression is true if at least one item is found both in customVal.value and in value.

    Option2: Field must contain all values

    If with my example you expect to get only the second field because all items in the array must be found in the variable and in customVal.value then you should use lodash's difference and check if the result is an empty array. Something like:

    difference(value, customVal.value).length === 0
    

    In this case the order of the arguments is important.

    This expression is true if all items that are in value are also found in customVal.value. Other values in customVal.value won't be returned by difference because we used value as the first argument.

    (This option can also be achieved with intersection and comparing the result's length to the argument's array length)