Why does R.all with R.both does not equal R.allPass with the same arguments? - ramda.js

I'm just learning while doing ramda.js. Well, there are many ways to reach a goal with ramda, but there is on thing I do not understand.
I would like to check the input for an array of strings that all match one regular expression. I thought I could do it R.all(R.both(isString, isRegExp)), but it seems to deliver a true when the input is a number.
As expected R.allPass([isString, isRegExp]) gives a false with a number input.
But can anyone please explain me why R.all is returning a true? Or what and where is mistake (in thinking)?
Complete code:
var isString = R.is(String),
isMyRegExp = R.test(/^[a-z]+$/),
isMyRegExpString = R.both(isString, isMyRegExp),
isArrayOfMyRegExpStrings = R.all(isMyRegExpString),
isArrayOfMyRegExpStringsPass = R.allPass([isString, isMyRegExp]),
result = {
'all': isArrayOfMyRegExpStrings(9),
'allPass': isArrayOfMyRegExpStringsPass(9)
};
console.log(result);
// {
// all: true,
// allPass: false
// }
https://codepen.io/Eisenhardt/pen/PKLZqj
PS:
I know that I could shorten conditions with just the regexp, but there could be other situations where I need both conditions to be true. eg. isArrayOfNumber and sumOfNumbersOver50.

The second argument to R.all is expecting a list of values to test. Due to the way the function is implemented it is treating the 9 in your example as an empty list, resulting in a vacuous truth and evaluating to true.

Related

How can I save part of a string in an alias using Cypress?

I'm trying to save just a number from a string I get from a paragraph but when I try to asign an alias to it and then check the value it returns undefined. I've tried a few solutions I found but none of those seem to work for me. These are two ways I tried (I tried another one similar to the second one but using split, had same result). The console.log inside of the 'then' doesn't show in the console, and when I try the alias after the code is when I get undefined.
cy.get('p')
.eq(1)
.should('have.text', '/[0-9]+/g')
.as('solNumber')
cy.get('p')
.eq(1)
.invoke('text')
.then((text)=>{
var fullText = text;
var pattern = /[0-9]+/g;
var number = fullText.match(pattern);
console.log(number);
})
.as('solNumber')
Please convert with + operator and return the numeric value if you want numeric type to be stored.
cy.get('p').eq(1)
.invoke('text')
.then(fullText => {
const number = fullText.match(/[0-9]+/);
return +number // text to numeric
})
.as('solNumber')
cy.get('#solNumber')
.should('eq', 42) // numeric type
});
Running your 2nd code on this,
<p>21</p>
<p>42</p>
gives the correct outcome
cy.get('p')
.eq(1)
.invoke('text')
.then((text)=>{
var fullText = text;
var pattern = /[0-9]+/g;
var number = fullText.match(pattern);
console.log(number); // logs 42
})
.as('solNumber')
cy.get('#solNumber')
.should('eq', '42') // passes
So, you need to inspect the DOM, it looks like it's not what you expect.
The first attempt you were passing a jquery element to the .should() and although some chainers change the subject yours did not so it saved the jquery element as solNumber.
The second attempt invokes the .text() which was passed to the .then() it logs the number correctly. However, you did not return anything at the end of the .then() block, therefore, solNumber should hold the entire paragraph.
This should help you out to extract the specific number and save it as an alias.
cy.get('p')
.invoke('text')
.invoke('trim')
.then(paragraph => {
const matcher = /some/
expect(paragraph).to.match(matcher) // check number is there
const indexOfText = paragraph.match(matcher) // get index of match text
return paragraph.substring(indexOfText.index, indexOfText.index + indexOfText[0].length) // return substring
})
.as('savedText')
cy.get('#savedText')
.then(cy.log) // will print out the number you seek

Why is kotlin stream evaluating an .all predicate to true where the first Iterable is empty

I have a List of objects.
importerResponse.applications is empty (size=0)
This is my code:
val isDeployed = importerResponse.applications
.flatMap(Application::instances)
.map(Instance::state)
.all { state -> DEPLOYED == state }
isDeployed is true in this case. How can this be? I want it to resolve into false if applications is empty.
Why would you want that? All the elements in the collection satisfy your predicate.
You can check the documentation:
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/all.html
If you want you can explicitly check for the collection being empty.
This should give you what you want:
val isDeployed = importerResponse.applications
.flatMap(Application::instances)
.map(Instance::state)
.count { state -> DEPLOYED == state } > 0```
The all method might be looking for any element that doesn't meet the condition, since you don't have any, it defaults to true.
You can achieve what you want by doing something similar to this:
val isDeployed = importerResponse.applications
.flatMap(Application::instances)
.map(Instance::state)
.let { it.size() > 0 && it.all { state -> DEPLOYED == state } }
Note that let allows you to reuse the same expression without recalculating it twice.
It can be a little bit confusing, why "any" returns "false" on empty collections, but "all" return true, because "all" seems to be more limiting than "any" (based on human language).
But if you ask as one example "if all persons in a room are male", than that's still true, if the room is empty. 0 out of 0 persons are ALL.

Trying to setState using eval() function (React Native)

I'm trying to set multiple states in a for loop to be false or true depending on whether they meet the (if statement) requirement. The for loop will loop through an array of strings, each string represents a state. But I can't seem to use eval within this.setState function...
I have tried researching online but none of the solutions match my problem or what I'm trying to solve. I even tried eval(this.state.anything) = false but it still doesn't work and shows a left hand assign invalid error.
let businessState = [
"this.state.groupName",
"this.state.groupOwnerName",
"this.state.groupDesc",
"this.props.profile._id",
"this.state.businessName",
"this.state.businessDesc",
"this.state.businessRegNo",
"this.state.businessType",
"this.state.businessEmail",
"this.state.businessTel",
"this.state.businessWeChat",
"this.state.businessRegPhotoUri",
"this.state.businessSignPhotoUri"
];
var temp = ""
for (i = 0; i < businessState.length; i++) {
if (eval(businessState[i]) == ""){
temp = businessState[i]+ "Error"
this.setState({
eval(temp): true
})
}
}
As you can see from the code above, I want to evaluate the state, and if the value that this particular state holds is an empty string "", I want to set this state name + "Error" (For example, if this.state.email is empty string "" I want to set this.state.emailError to true.
Instead of this.setState({eval(temp): true}) try this.setState({[temp]: true}). The brackets will output the string value stored in temp as a variable name in setState.
This article gives a good explanation
This Stack Overflow question and the accepted answer also should help

Adding to List Prints true in Velocity

I am trying to add some string values to a list in Velocity. When I run the code it works alright. But the line where it adds the value prints true. Is it always like that in Velocity? I am new to Velocity templates, so cant figure it out myself.
#set ($uniqueInterfaces = [])
#if($ipv4interfaceName == $ipv6interfaceName)
$uniqueInterfaces.add($ipv4interfaceName)
#end
Its part of larger code with a nested foreach. It has two matches in it, so the output is:
true
true
I do not need this true being printed at all!
Java's List#add method returns boolean, that's why this return value is printed in your html output.
You can hide it simply by assigning the output of the add method to a dummy variable:
#set ($uniqueInterfaces = [])
#if($ipv4interfaceName == $ipv6interfaceName)
#set ($swallow = $uniqueInterfaces.add($ipv4interfaceName))
#end

How to check if a TypedPipe or a ValuePipe are empty in Scalding?

In Scalding, suppose you have a TypedPipe[Long] or ValuePipe[Long]. How would you go about checking whether they are empty in the most elegant/efficient way?
Currently testing the following:
val isTPEmpty: Boolean = typePipe.equals(TypedPipe.empty)
val isVPEmpty: Boolean = valuePipe.equals(EmptyValue)
Or, to make it more generic:
def isTypedPipeEmpty[A](typedPipe: TypedPipe[A]): Boolean = {
val emptyTP: TypedPipe[A] = TypedPipe.empty
typedPipe.equals(emptyTP)
}
UPDATE: this doesn't work (will return false for an empty TypedPipe). Appreciate any inputs.
After speaking to several people on this, there is no straight solution simply because a TypedPipe is distributed, and checking whether it is empty is "expensive", therefore one should avoid this as much as possible.
If you absolutely have no choice, what worked for me was something "ugly" as creating a temporary empty TypedPipe, then calling mapWithValue on my ValuePipe, and if it is empty do X, otherwise do Y. Something like:
TypedPipe.from(List()).mapWithValue(valuePipe) { case (temp, valuePipe) => if (valuePipe.isEmpty) doX else doY }
But again, cumbersome.