Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One of strings in array to match an expression

The Problem:

I have an array of promises which is resolved to an array of strings. Now the test should pass if at least one of the strings matches a regular expression.

Currently, I solve it using simple string concatenation:

protractor.promise.all([text1, text2, text3]).then(function (values) {
    expect(values[0] + values[1] + values[2]).toMatch(/expression/);
});

Obviously, this does not scale well and is not particularly readable.

The Question:

Is is possible to solve it using a custom jasmine matcher, or jasmine.any() or custom asymmetric equality tester?

like image 970
alecxe Avatar asked Jun 20 '16 15:06

alecxe


People also ask

How do you match an array to a string?

String Matching in an Array - LeetCode. Given an array of string words . Return all strings in words which is substring of another word in any order. String words[i] is substring of words[j] , if can be obtained removing some characters to left and/or right side of words[j] .

Can I use regex in array?

This is possible when regex applied on this string array. But Build Regular Expression Action only can take String as a Input not a Array of Strings.

How do I check if a string is in regular expressions?

If you need to know if a string matches a regular expression RegExp , use RegExp.prototype.test() . If you only want the first match found, you might want to use RegExp.prototype.exec() instead.


1 Answers

As said in the comments, although I initially use map, reduce would allow you to do what you need, and in this caste at least makes a lot more sense:

protractor.promise.all([text1, text2, text3]).then(function (values) {
    expect(
        values.reduce(function(p, v) {
            return v.match(/expression/) || p;
        }, false)
    ).toBe(true);
});

Or writing the same thing, but using ES6 arrow functions:

protractor.promise.all([text1, text2, text3]).then(function(values) {
    exptect(
        values.reduce( (p, v) => v.match(/expression/) || p, false )
    ).toBe(true);
});

Both do the same thing, the reduce callback will default to false, until the v.match expression evaluates to true.
I'm assuming this is obvious to most people, but I thought I'd provide both syntaxes and some explanation for future reference


Perhaps this solution could be optimized a bit more, to stop matching the pattern once a single match has been found:

protractor.promise.all([text1, text2, text3]).then(function (values) {
    expect(
        values.reduce(function(p, v) {
            return p || !!v.match(/expression/);
        }, false)
    ).toBe(true);
});

All I did was to use the current reduce value as default (once that has been set to true, there's no point in testing any other string value). To ensure v.match evaluates to a boolean instead of an array, I just used !!v.match(). That part is optional though. In ES6, the same thing looks like this:

protractor.promise.all([text1, text2, text3]).then(function(values) {
    exptect(
        values.reduce( (p, v) => p || !!v.match(/expression/), false )
    ).toBe(true);
});

This might perform better with big data sets (considering the match calls stop once the first match was found, as opposed to v.match being called every time).

like image 59
Elias Van Ootegem Avatar answered Oct 17 '22 07:10

Elias Van Ootegem