Is
The is
function is closely related to .isEq()
is
implements a rich library of functions for composing predicate expressions (a function that returns true
or false
)
These can be used in is.filter()
, is.case()
statements and other conditional logic
See .case() and .filter() for mores details
is
allows the chaining and composing of tests in the generic form of is.something()
It can be used to test for:
- Type using Type Operators
- Compared to values using Comparison Operators
- Node specific values using Node Functions
- Tests may be combined or customized using Logical Operators
For working with nodes, or objects, is has 2 further powerful structures:
- To test a property with a predicate operator is.prop
- To test if multiple conditions are met
is.match
Type Operators
.number
Number.string
String.date
Date.boolean
Boolean.blank
Tests for blank values.found
Tests to see if property exists
number
To test if a property value is a number the .number
operator can be combined with the logical operator .not
node.currentSalary.case(is.not.number, "Salary Data Error")
In this example the Current Salary property is a number formatted to display with no decimal places and including the $ symbol
- A. This node is a number so the expression passes the value as a result as the example
case()
statement has no fallback "else" option included - B. This node has the $ symbol included in the entered data so is actually a text string and therefore fails the test. The node value is also highlighted by the red underline indicating the wrong format
date
Similar expression logic can be used to test if property values are other specified types
node.dateofbirth.case(
is.not.date, "DOB Data Error")
In this example the Date of Birth property is tested to ensure it is a date
- A. As this value passes the test the value of the full date is returned as the result
- B. This date has been incorrectly entered as a string and therefore the result "DOB Data Error" is returned
found
The expression is.found
tests to see if a specified property can be found, in this example it is combined with a .not
operator to create an expression returning the warning string "Salary property is not present" if the property "salary" cannot be found
node.salary.case(is.not.found, "Salary property is not present")
In the example the correct property name is "current salary" so the expression returns the warning as it is unable to find a property "salary"
multiple types
It is also possible to test a value against multiple types and return different results
node.inScope.case(
is.blank, "Not yet assessed",
is.not.boolean, "Scope Data Error")
Here the property "in scope" is tested for two conditions
- A. This value is blank so returns the first message
- B. This value is not a boolean so returns the second message
Comparison operators
.eq()
Equal.gt()
Greater than.lt()
Less than.gtEq()
Greater than or equal.ltEq()
Less than or equal.in()
Looks for specified value in specified object.true
Tests if condition is true.false
Tests if condition is false
Greater Than, Less Than and Equal
These comparison operators provide the same function as the Comparison Operator signs e.g..ltEq()
is the equivalent of <=
and they can be used to perform conditional logic and may be used singularly
e.g.
node.outgoing_count.case(is.gt(10), "Too many direct reports")
In this example a single condition is tested to return the string "Too many direct reports" if the outgoing count of selected node is greater than 10
Multiple conditions may be combined to conduct more complex comparisons
node.outgoing_count.case(
is.gt(10), "Too many direct reports",
is.gtEq(1).ltEq(3), "Too few direct reports")
Here the original expression has been extended with a second clause which returns the string "Too few direct reports" if the outgoing count is between 1 and 3 inclusive
Further clauses may be added to the expression within the .case( )
with each one separated by ,
node.outgoing_count.case(
is.gt(10), "Too many direct reports",
is.gtEq(1).ltEq(3), "Too few direct reports",
is.gt(3).ltEq(10), "On target")
is.eq()
may also be used with text strings such as this example
node.department.case(is.eq("HR"), "Human Resources")
True or False
The operators .true
and .false
are the opposite of each other and can be used to simply a test if a condition is true or false and return a specified value for each
e.g.
node.isLeaf.case
(is.false, "Manager",
is.true,"Not a Manager")
This is the equivalent of:
node.isLeaf.case(is.false, "Manager", "Not a Manager")
or
node.isLeaf.case(is.true, "Not a Manager", "Manager")
As both of these examples include a fallback "else" statement within the case
( )
Node functions
is.root
is.leaf
is.parent
is.child
is.orphan
is.duplicate
is.new
is.updated
is.Generated
Node functions include those created by Orgvue for datasets as Generated Properties and may be used to test the selected nodes for various values
Logical operators expand the scope of conditional logic expression to create even more powerful tests
And
.and
is used to join two clauses so that both conditions must be met to return "True"
However the .and
operator is generally optional
e.g.
node.outgoing_count.case(is.gtEq(1).and.ltEq(3))
Is the equivalent of
node.outgoing_count.case(is.gtEq(1).ltEq(3))
As this expression already requires both conditions are met to return "True"
Not
not
may be used with any other operator to invert the function
node.dateofbirth.case(
is.not.date, "DOB Data Error")
The use of .not
tests if the object is not a date
In
.in
performs the same operation as "contains one of" and is similar in usage to an "or" condition
nodes().filter
(is.prop("Absence Detail",
is.in("Stress", "Other")))
In this example the expression has returned a collection of nodes who have the "Absence Detail" reason of either "Stress" OR " Other" using the .in
function
is prop
The function is.prop()
takes the generic form is.prop("property name", predicate)
e.g.
node.case(is.prop("Absence Days", is.gt(5)))
While this is the equivalent of
node.absenceDays.case(is.gt(5))
The benefit of using is.prop
is that more than one property may be tested for a condition within the expression
e.g.
node.case
(is.prop("Absence Days", is.gt(5))
.is.prop("Absence Detail", is.eq("Stress")))
Here the selected node is tested against two clauses, that the "absence days" are greater than 5 and that the absence detail is "stress"
Changing the expression from node.case
to nodes().filter
nodes().filter
(is.prop("Absence Days", is.gt(5))
.is.prop("Absence Detail", is.eq("Stress")))
Returns a collection of nodes matching the condition instead of the previous true or false
When chaining multiple is.prop
clauses the subsequent .is.
are optional
nodes().filter
(is.prop("department", is.in("Sales", "Finance"))
.is.prop("location", is.eq("UK"))
.is.prop("tenure years", is.gt(3)))
is the same as:
nodes().filter
(is.prop("department", is.in("Sales", "Finance"))
.prop("location", is.eq("UK"))
.prop("tenure years", is.gt(3)))
Chaining of multiple .prop()
calls is the equivalent of an AND condition as each clause has to be met to return true
isEmpty
The isEmpty() method checks whether a string is empty or not
This method returns true if the string is empty (length() is 0), and false if not
Logical Operators
.every()
.some()
.atLeast()
.atMost()
.exactly()
When using multiple is.prop
clauses it is also possible to add logical operators to define how many clauses need to be met
Note that when using these operators each is.prop()
clause is separated by a ,
instead of the .
notation used in the chaining example above
Every
The .every
operator means every clause must be true (equivalent to AND) in this example it returns the same results as the chained version above
nodes().filter(is.every(
is.prop("department", is.in("Sales", "Finance")),
is.prop("location", is.eq("UK")),
is.prop("tenure years", is.gt(3))))
Some
The .some
operator means at least one of the clauses needs to be true
nodes().filter(is.some(
is.prop("department", is.in("Sales", "Finance")),
is.prop("location", is.eq("UK")),
is.prop("tenure years", is.gt(3))))
In the example data used 1233 nodes matched at least one clause
At Least, At Most
atLeast(value)
and atMost(value)
allow you to specify a minimum or maximum number of clauses to be met
nodes().filter(is.atLeast(3,
is.prop("department", is.in("Sales", "Finance")),
is.prop("location", is.eq("UK")),
is.prop("age", is.lt(50)),
is.prop("current Salary", is.gtEq(50000)),
is.prop("tenure years", is.gt(3))))
Here at least 3 of the 5 possible clauses must be met
nodes().filter(is.atMost(2,
is.prop("department", is.in("Sales", "Finance")),
is.prop("location", is.eq("UK")),
is.prop("age", is.lt(50)),
is.prop("current Salary", is.gtEq(50000)),
is.prop("tenure years", is.gt(3))))
While in this example a maximum of any two clauses can be met
Exactly
exactly()
completes this set of logical operators allowing a specific number of clause to be defined
nodes().filter(is.exactly(4,
is.prop("department", is.in("Sales", "Finance")),
is.prop("location", is.eq("UK")),
is.prop("age", is.lt(50)),
is.prop("current Salary", is.gtEq(50000)),
is.prop("tenure years", is.gt(3))))
Match
is.match()
is another alternative to the multiple chained is.prop
nodes().filter(
is.match({
department: is.in("Sales", "Finance"),
location: "UK",
tenureYears: is.gt(3),}))