简体   繁体   中英

Javascript Filter an array based on multiple conditions using native functions

I have a situation where I need to filter an array of objects based on certain conditions. And here what it is

  • There is an error response and the response is an array of objects. Each object has nodes message , type , keyValues
  • keyValues is an array and may have 3 different items at-most. The nodes for each element are key & value
  • key can have one of the following 3 values by-date , by-unique-object , by-related-object
  • value for by-date will have the value as date object
  • value for by-unique-object , by-related-object will have object as

    value: {
       uri: "object-uri-1"
    }

  • The uri has specific pattern and same for both of the types by-unique-object , by-related-object .

So, from the given error array I need to filter only the records which got only by-date and should not have other 2 types with those types of URI pattern

Here what I did -

let errors = [
    {
        message: "Error message 1",
        type: "error",
        keyValues: [
            {
                key: "by-date",
                value: {
                    date: {year:2020, month: 4, day: 6}
                }
            },
            {
                key: "by-unique-object",
                value: {
                    uri: "object-uri-1"
                }
            },
            {
                key: "by-related-object",
                value: {
                    uri: "object-uri-1"
                }
            },
        ]
    },
    {
        message: "Error message 2",
        type: "error",
        keyValues: [
            {
                key: "by-date",
                value: {
                    date: {year:2020, month: 4, day: 5}
                }
            }
        ]
    },
    {
        message: "Error message 3",
        type: "error",
        keyValues: [
            {
                key: "by-date",
                value: {
                    date: {year:2020, month: 4, day: 6}
                }
            },
            {
                key: "by-unique-object",
                value: {
                    uri: "object-uri-3"
                }
            }
        ]
    },
    {
        message: "Error message 4",
        type: "warning",
        keyValues: [
            {
                key: "by-unique-object",
                value: {
                    uri: "object-uri-4"
                }
            },
            {
                key: "by-related-object",
                value: {
                    uri: "object-uri-4"
                }
            }
        ]
    },
    {
        message: "Error message 5",
        type: "warning",
        keyValues: [
            {
                key: "by-date",
                value: {
                    date: {year:2020, month: 4, day: 8}
                }
            },
            {
                key: "by-related-object",
                value: {
                    uri: "object-uri-4"
                }
            }
        ]
    },
    {
        message: "Error message 6",
        type: "warning",
        keyValues: [
            {
                key: "by-date",
                value: {
                    date: {year:2020, month: 4, day: 9}
                }
            }
        ]
    }
];
const matchObjectUriPattern = (uri) => /object-uri-.*/g.test(uri);
const hasByDate = (item) => item.key === "by-date" && item.value && item.value.date;
const hasUniqueObject = (item) => item.key === "by-unique-object" && matchObjectUriPattern(item.value.uri);
const hasRelatedObject = (item) => item.key === "by-related-object" && matchObjectUriPattern(item.value.uri);


const checkOnlyByDate = (error) => {
    let keyValues = error && error.keyValues ? error.keyValues : [];
    let byDate = keyValues.find(hasByDate);
    let byUniqueObject = keyValues.find(hasUniqueObject);
    let byRelatedObject = keyValues.find(hasRelatedObject);

    return byDate && (!byUniqueObject && !byRelatedObject);
};

const filteredErrors = errors.filter(checkOnlyByDate);

console.log(JSON.stringify(filteredErrors)); 

What I did works well, but is there a better way to do it? Or some better way to handle this?

I like your solution: Based on your requirements I came up with:

const filteredErrors = errors.filter(({keyValues}) => 
  keyValues.every(({key}) => key === "by-date"))

Which only returns those error messages whose keyValues array only contains objects with key === "by-date"

I can't say this is better or worse than what you provided because I'm not sure how else you might be using this code. But I wanted to add my own interpretation of the problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM