How do I check if a string contains a substring in appway script? - appway

The CONTAINS($val1, $val2, $delim) function in AppwayScript checks whether a delimiter separated string contains a certain value as a substring.
So, e.g.:
CONTAINS('a|b|c', 'b', '|') == true
but
CONTAINS('aa|bb|cc', 'b', '|') == false
How do I perform a simple string inclusion test in AppwayScript?

Instead, try:
MATCH('aa|bb|cc', 'b')

Related

How I build Dart Regexp Properly?

Goal of this expression is separate mathematic calculations into operators, symbols, numbers and brackets.
For example:
Input string: 1+3-6*(12-3+4/5)
Output list: 1, +, 3, -, 6, *, (12-3+4/5)
So I built this expression.
It is working on the web page, but in the Dart code this happens:
final calculationExpression = RegExp(
r"/(\(([a-zA-Z0-9-+/*]+)\))|([a-zA-Z0-9]+)|([+/*-]{1})/g",
unicode: true,
multiLine: true,
);
...
List<String> operators = calculationsString.split(calculationExpression); /// Output: ["", "+", "-", ...]
What did I do wrong?
The syntax /pattern/g is used to create regular expression literals in JavaScript (and sed and some other languages), just as quotes are used to create string literals. Dart doesn't have regular expression literals; you instead must invoke the RegExp constructor directly. Combining a regular expression literal syntax with an explicitly constructed RegExp object makes no sense. When you do RegExp(r'/pattern1|pattern2|pattern3/g'), you're actually matching against /pattern1 (pattern1 prefixed with a literal / character) or pattern2 or pattern3/g (pattern3 followed by a literal string /g).
String.split does not split the input string such that each element of the result matches the pattern. It treats all matches of the pattern as separators. Consequently, the resulting list will not have any elements that match the pattern, which is the opposite of what you want. You instead want to find all matches of the pattern in the string. You instead can use RegExp.allMatches if you additionally verify that the input string contains only matches from the regular expression.
Putting it all together:
void main() {
final calculationExpression = RegExp(
r"(\(([a-zA-Z0-9-+/*]+)\))|([a-zA-Z0-9]+)|([+/*-]{1})",
unicode: true,
multiLine: true,
);
var calculationsString = '1+3-6*(12-3+4/5)';
// Prints: [1, +, 3, -, 6, *, (12-3+4/5)]
print(calculationsString.tokenizeFrom(calculationExpression).toList());
}
extension on String {
Iterable<String> tokenizeFrom(RegExp regExp) sync* {
void failIf(bool condition) {
if (condition) {
throw FormatException(
'$this contains characters that do not match $regExp',
);
}
}
var matches = regExp.allMatches(this);
var lastEnd = 0;
for (var match in matches) {
// Verify that there aren't unmatched characters.
failIf(match.start != lastEnd);
lastEnd = match.end;
yield match.group(0)!;
}
failIf(lastEnd != length);
}
}
You put the JavaScript regexp literal slashes and flags inside the Dart string.
If you remove the leading / and trailing /g, you get the RegExp you intended to.
The multiLine and unicode flags are unnecessary (your regexp doesn't use any feature affected by those)
The Dart split function does not emit capture groups, so you probably want to look at getting the matches, not removing them, which is what split does.
All in all, try:
final calculationExpression = RegExp(
r"\([a-zA-Z\d\-+/*]+\)|[a-zA-Z\d]+|[+/*\-]");
List<String> tokes =
calculationExpression.allMatches(calculationsString).toList();

How to compute each cell of a line in an array with Ruby on Rails 5.2?

While importing from an excel file to a database, I need to format a hierarchy so it appears with leading zeros:
10.1.1.4 must be transformed into 1.010.001.001.004
I tried to iterate through and concatenate the elements:
record.hierarchy = spreadsheet.cell(i,2).split('.').each do |t|
index = index || '1.'
index = index + '.' + (((t.to_i + 1000).to_s).last(3))
end
which actually returns and array of ["10", "1", "1", "4"], not computed. I would expect this to return the last evaluated value: index
I tried to compute it directly inside the array:
record.hierarchy = '1.' + (((spreadsheet.cell(i,2).split('.').each).to_i + 1000).to_s).last(3).join('.')
which raises an undefined method to_i for enumerator.
Can someone explain me how to structure and solve this computation?
Thanks
Use #rjust.
'10.1.1.4'.split('.').map { |l| l.rjust(3, '0') }.join('.')
Your first solution uses assignment with #each. #each will not return modified array.
It is not necessary to convert the string to an array, modify the elements of the array and then join the array back into a string. The string can be modified directly using String#gsub.
str = '10.1.1.4'
('1.' + str).gsub(/(?<=\.)\d+/) { |s| sprintf("%03d", s.to_i) }
#=> "1.010.001.001.004"
See Kernel#sprintf.
(?<=\.) is positive lookbehind that requires the matched digits to be preceded by a period. I've assumed the string is known to contain between one and three digits before and after each period.
You can try different function for leading zeroes and inject to not set default value inside the loop
record.hierarchy = spreadsheet.cell(i,2).split('.').inject('1') do |result, t|
result + '.' + t.rjust(3, '0')
end

Intersection of 2 array of strings with different upper and lower case

I want to get the intersection of 2 arrays of strings. The first array has different upper and lower case. The resulting array I want should respect the first arrays casing, but the comparison between the 2 should ignore the upper/lower case. E.g.
letters = ['Aaa', 'BbB', 'CCC']
permitted = ['aaa', 'bbb']
The result should be:
['Aaa', 'BbB']
Im doing:
letters.map(&:downcase) & permitted.map(&:downcase)
But this returns ['aaa', 'bbb']
What's a neat way of doing this? The longer way of doing it is:
letters.each { |letter|
if permitted.include?(letter.downcase)
accepted.push(letter)
end
}
But is there a shorter/neater way?
You can use select:
search = permitted.map(&:downcase)
letters.select{|letter|
search.include?(letter.downcase)
}
Or even neater (imho):
-> search {
letters.select{|x| search.include?(x.downcase)}
}.call(permitted.map(&:downcase))
Demonstration
There's a method for comparing string in a case-insensitive manner, String#casecmp:
letters = ['Aaa', 'BbB', 'CCC']
permitted = ['aaa', 'bbb']
letters.select{|l| permitted.detect{|p| p.casecmp(l) == 0 } } # => ["Aaa", "BbB"]
You can also use regular expressions. :)
letters = ['Aaa', 'BbB', 'CCC']
permitted = ['aaa', 'bbb']
letters.grep(Regexp.new(permitted.join('|'), Regexp::IGNORECASE)) # => ["Aaa", "BbB"]

Hash mixed value type comparison

I am trying to compare an Variable to a value within a hash, but the hash can be queried using both Numeric and String arguments.
ED_CONTRIBUTIONS = {
1 => {
db_code: 1,
name: 'Provision of housing and transport',
abbreviation: 'Provisions',
group: 'Social development contributions'
}
}
I use a method like this to do the comparison:
def find_item(field, value)
value.downcase if value.is_a? String
applicable_items.find { |k,v| v[field] == value}.andand.last || {}
end
but sometimes the v[filed] is the db_code and as a result a digit. how can i make it so that if v[field] is a string that it be downcased? or rather how does one check the state of the value of a hash in such an instance.
You can check if it's a string like this v[field].kind_of? String, and downcase it if it is.
Or you can just v[field].to_s.downcase it without checking the variable type.
You can just parse it to a String:
value.to_s.downcase
and then you don't need to investigate if the value is a String

How can I trim all elements in a list using Groovy?

I need trim all elements in a list in groovy or grails?
what is the best solution
Assuming it is a list of strings and you want to trim each string, you can do it using the spread operator (*.)
list = [" abc ", " xyz "]
list*.trim()
You can use the collect method or the spread operator to create a new list with the trimmed elements:
def strs = ['a', ' b', ' ']
assert strs.collect { it.trim() } == ['a', 'b', '']
assert strs*.trim() == ['a', 'b', '']
In those cases, the original list isn't modified. If you want to trim the strings in place, you'll need to iterate through the list with an index:
for (i in 0..<strs.size()) {
strs[i] = strs[i].trim()
}

Resources