2
$\begingroup$

Perhaps this is trivial - if so I am happy to delete.

I have a mixed list of objects that are Entities and strings. Is there a way of telling the difference between them ?

For example we have the following list:

list = {Entity["Country", "France"],Entity["Country", "Germany"],"New Country"}

and I want to process this data in a way that I can work out whether this is an entity or not.

i.e.

 Map[EntityQ[#]&,list]

which would give the output {True,True,False}

$\endgroup$
1
  • 1
    $\begingroup$ There was similar question on stack exchange in the past about how to define a SymbolQ here. If the list elements contain either entities or strings you could also use Not@*StringQ. $\endgroup$ Nov 20, 2022 at 11:47

3 Answers 3

2
$\begingroup$

Note : This answer uses internal functions so it might not work in the future.


Code

entityQ[entity_] := 
  Internal`PossibleEntityQ[entity] && 
   EntityFramework`EntityExistsQ[entity];

I wrote a function that searches all functions and variables in Mathematica including those that are internal:

 all…names[name_]:= Information[{___~~"`"~~___~~name~~___ ,___~~name~~___~~"`"~~___}]//Sort;

Using :

all…names["Entity*Q"]

one finds a list with multiple matching names. The three considered in the following are :

  • Internal`PossibleEntityQ

  • EntityFramework`EntityExistsQ

  • EntityFrameworkPredicatesPrivate`iEntityExistsQ

One may check the definitions of these functions using, for example :

<< GeneralUtilities`

PrintDefinitions@EntityFramework`EntityTypeExistsQ

Consider some examples to see what these functions do.

EntityFramework`Predicates`Private`iEntityExistsQ[
 Entity["randrand", "rand"]]

(* False *)

and

EntityFramework`EntityExistsQ[
 Entity["randrand", "rand"]]

(* False *)

But

EntityFramework`Predicates`Private`iEntityExistsQ[
 Entity["Company", "StackExchange::n59g4"]]

(* True *)

EntityFramework`EntityExistsQ[
 Entity["Company", "StackExchange::n59g4"]]

(* True *)

If the object does not have the expected structure of an Entity for example "word" or Entity["english"] instead of Entity["Language", "English::385w8"] then

EntityFramework`Predicates`Private`iEntityExistsQ

throws an error while

EntityFramework`EntityExistsQ

does not evaluate.

One can use the following internal function first that seems to just test whether the structure is correct:

Internal`PossibleEntityQ[Entity["randrand", "rand"]]

(* True *)

Internal`PossibleEntityQ[Entity["rand"]]

(* False *)

Internal`PossibleEntityQ[42]

(* False *)

So one can combine those two functions to make an entityQ :

entityQ[entity_] := 
  Internal`PossibleEntityQ[entity] && 
   EntityFramework`EntityExistsQ[entity];

Verify that the code works:

entityQ[42]

(* False *)

entityQ[Entity["randrand", "rand"]]

(* False *)

entityQ[Entity["Company", "StackExchange::n59g4"]]

(* True *)

$\endgroup$
3
$\begingroup$

You can use a function that expects an Entity object and will throw an error if not given. CanonicalName is an example.

CanonicalName throws CanonicalName::noent when not provided an Entity. It returns a string that can be tested for success. I only Quiet this message so other errors will get passed up.

entityQ[expr_] := Quiet[Head@CanonicalName[expr] === String, {CanonicalName::noent}]

then

entityQ[Entity["apple"]]
False
entityQ[Entity["Planet", "Earth"]]
True

Other messages will be passed up and entityQ will still provide a result.

entityQ[1/0]

Power::infy: Infinite expression 1/0 encountered.

False

Hope this helps.

$\endgroup$
2
$\begingroup$

One way is to define the following function which would have these properties:

entityQ[ent_] := Entity === ent[[0]];
Map[entityQ[#] &, list]

output is:

{True,True,False} 

as hoped.

$\endgroup$
1
  • 2
    $\begingroup$ entityQ[Entity["apple"]] returns true but Entity["apple"] is not an entity object. $\endgroup$
    – Edmund
    Nov 20, 2022 at 18:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.