How to check if a property value is a list in Memgraph? - memgraphdb

I am using Memgraph Platform 2.6.5 and I want to check whether the property of a node is a list. I see there is a type function for relationships but would be good to have some kind of data type filtering for properties. I tried using the size function but it also works on strings and paths so it can't tell if a property is a list or not. Any idea on how to do that?

Here is an example of a small trick on how to do that:
If you have a node with list and string properties:
CREATE (n:Node {list: [1, 2, 3, 4, 5, 6, 7, 8], str: "myString"});
And then run:
MATCH (n:Node)
RETURN size(n.list + 11) = size(n.list)+1 AS isList;
I get true.
Otherwise, if I run this:
MATCH (n:Node)
RETURN size(n.str + 11) = size(n.str)+1 AS isList;
I get false.
This is because if you add a number consisting of two chars to a string, you get string which size has increased by 2. But, if you add the same number to a list, list size increased by 1.
Besides that, you can always create a custom procedure in Memgraph to extend Cypher query language. These procedures can be written in Python, C/C++ or Rust, and here is a how-to guide.

Related

Filtering erlang ets tables without using guard clauses

In elixir, I would like to be able to filter an ets table using a function.
I currently have a simple ets table example in the iex shell...
iex> :ets.new(:nums, [:named_table])
:nums
iex> :ets.insert :nums, [{1}, {2}, {3}, {4}, {5}]
true
fun = :ets.fun2ms(fn {n} when n < 4 -> n end)
[{{:"$1"}, [{:<, :"$1", 4}], [:"$1"]}]
:ets.select(:nums, fun)
[1, 3, 2]
This all works as you would expect. My question relates to the function being used to query the ets table. Currently it uses a guard clause to filter for results less than 4.
I would like to know if there is a way put the guard clause syntax into the function body. For example...
iex> fun2 = :ets.fun2ms(fn {n} -> if n < 4, do: n end)
but if I do this then I get the following error...
Error: the language element case (in body) cannot be translated into match_spec
{:error, :transform_error}
Is something like this possible?
It turns out, this is the only way to go
From erlang documentation
The fun is very restricted, it can take only a single parameter (the object to match): a sole variable or a tuple. It must use the is_ guard tests. Language constructs that have no representation in a match specification (if, case, receive, and so on) are not allowed.
More info about Match Specifications in Erlang

Programming and data structures

Suggest a data structure for representing a subset S of integers from 1 to n. Following operations on the set S are to be performed in constant time (independent of cardinality of S).
You may assume that the data structure has been suitable initialized.
(i). MEMBER (X):
Check whether X is in the set S or not
(ii). FIND-ONE(S): If S is not empty, return one element of the set S (any arbitrary element will do)
(iii). ADD (X): Add integer X to set S
(iv). DELETE (X): Delete integer X from S.
My analysis:-
I think hash table will work fine here ,but how will hash table work for FIND-ONES(S) operation.Because i might need to scan the entire has table to look for the present element.
You can just use a regular hashset for this in java. In the case of the FIND-ONE(S) what you would do is, call isEmpty(). If that returns false, use the built in iterator, and just get the first value the iterator returns.
A hash table would work, but you need to think about the specific implementation. If you use the compact version from Python 3.6, you can perform FIND-ONEs in constant time by inspecting the entries list.
For example, the dictionary:
d = {'timmy': 'red', 'barry': 'green', 'guido': 'blue'}
is represented as follows:
indices = [None, 1, None, None, None, 0, None, 2]
entries = [[-9092791511155847987, 'timmy', 'red'],
[-8522787127447073495, 'barry', 'green'],
[-6480567542315338377, 'guido', 'blue']]

Can I count on partition preserving order?

Say I have a sorted Array, such as this:
myArray = [1, 2, 3, 4, 5, 6]
Suppose I call Enumerable#partition on it:
p myArray.partition(&:odd?)
Must the output always be the following?
[[1, 3, 5], [2, 4, 6]]
The documentation doesn't state this; this is what it says:
partition { |obj| block } → [ true_array, false_array ]
partition → an_enumerator
Returns two arrays, the first containing the elements of enum for which the block evaluates to true, the second containing the rest.
If no block is given, an enumerator is returned instead.
But it seems logical to assume partition works this way.
Through testing Matz's interpreter, it appears to be the case that the output works like this, and it makes full sense for it to be like this. However, can I count on partition working this way regardless of the Ruby version or interpreter?
Note: I made implementation-agnostic because I couldn't find any other tag that describes my concern. Feel free to change the tag to something better if you know about it.
No, you can't rely on the order. The reason is parallelism.
A traditional serial implementation of partition would loop through each element of the array evaluating the block one at a time in order. As each call to odd returns, it's immediately pushed into the appropriate true or false array.
Now imagine an implementation which takes advantage of multiple CPU cores. It still iterates through the array in order, but each call to odd can return out of order. odd(myArray[2]) might return before odd(myArray[0]) resulting in [[3, 1, 5], [2, 4, 6]].
List processing idioms such as partition which run a list through a function (most of Enumerable) benefit greatly from parallel processing, and most computers these days have multiple cores. I wouldn't be surprised if a future Ruby implementation took advantage of this. The writers of the API documentation for Enumerable likely carefully omitted any mention of process ordering to leave this optimization possibility open.
The documentation makes no explicit mention of this, but judging from the official code, it does retain ordering:
static VALUE
partition_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arys))
{
struct MEMO *memo = MEMO_CAST(arys);
VALUE ary;
ENUM_WANT_SVALUE();
if (RTEST(enum_yield(argc, i))) {
ary = memo->v1;
}
else {
ary = memo->v2;
}
rb_ary_push(ary, i);
return Qnil;
}
This code gets called from the public interface.
Essentially, the ordering in which your enumerable emits objects gets retained with the above logic.

Parse.com query objects where the key's array value contains any of the elements

on https://parse.com/docs/js_guide#queries-arrays there is an example how to find objects where the key's array value contains each of the elements 2, 3, and 4 with the following:
// Find objects where the array in arrayKey contains all of the elements 2, 3, and 4.
query.containsAll("arrayKey", [2, 3, 4]);
However, I would like to find objects where the key's array value contains at least one (not necessarily all) of the elements 2,3, and 4.
Is that possible?
I'm not positive, but what happens if you try containedIn?
I think if you pass an array, it checks to see if any are contained.
query.containedIn("arrayKey", [2,3,4]);
I know that if you use equalTo with an array key and a singular value, it checks if the value is in the array and returns TRUE. I think this will do something similar and should work. I think it will check if any value in "arrayKey" is in the passed array. If any key object does, it will return the object.
swift 3.0
let Query:PFQuery = PFQuery(className: “className”)
Query.whereKey(“Field Name”, containedIn: array)// [“1”,”2”,”3”];

recursion in prolog - error in base case

I'm trying to write predicate range\3 that takes three parameters the first is the start, the second is the end and return the generated list in the third argument.
E.g rang(1,5,L).
L = [1, 2, 3, 4, 5]
I used this code
range(E,E,[E]).
range(S,E,L):-
S1 is S + 1,
range(S1,E,[S|L]).
But it does not work, when i used trace command to know where is the error i recognized that the base case is useless, I also tried the green cut !in the base case but it does not work range(E,E,[E]),!.
So, if any one knows what is the problem please help me
You're building the list in 'wrong' sense. Consider that when you'll call the base case, it will receive the consed list. How could match a single element list ? Try instead
range(S,E,[S|L]):-
S1 is S + 1,
range(S1,E,L).

Resources