BigQuery: How to see a part of the string? - string

I have a database that looks like
Alex,Anna,Peter
Alex
Alex,Peter
Alfons
Algebra,Geometry
Algebra,Physics
However I am only interested in the first expression before the comma. Meaning my perfect answer would be:
Alex
Alex
Alex
Alfons
Algebra
Algebra
So far I found the SPLIT function but it still returns me a bunch of values I am really not interested in. How to make it run efficiently?
Thanks

SELECT first(split(s,','))
FROM
(SELECT 'Alex,Anna,Peter' AS s),
(SELECT 'Algebra,Geometry' AS s);
Outputs:
Alex
Algebra

SPLIT could be expensive, since it translates string into repeated field, so here are two more alternative solutions:
SELECT IFNULL(LEFT(s, INSTR(s, ',') - 1), s)
FROM
(SELECT 'Alex,Anna,Peter' AS s),
(SELECT 'Algebra,Geometry' AS s),
(SELECT 'Alfons' AS s)
and
SELECT REGEXP_EXTRACT(s, r'([^,]*)')
FROM
(SELECT 'Alex,Anna,Peter' AS s),
(SELECT 'Algebra,Geometry' AS s),
(SELECT 'Alfons' AS s)

Related

How to concatenate strings in Prolog

I'm trying to make an IO-related exercise in Prolog but find it difficult working with strings.
The task is to take an input (an integer 1<=n<=180) and write is as a sum of three terms k*d where k=1,2, or 3 and 1<=d<=20.
For instance:
input: 180
output: triple 20, triple 20, triple 20
input: 96
output: triple 19, double 15, single 9
My problem is that I get error message:
"[some predicate I have tried]: Arguments are not sufficiently
instantiated".
Last thing I tried was a concatenate-predicate I found on another thread at StackOverflow Concatenation of Strings in Prolog. I think it looks nice but I still have the same problem. See my code below.
Before I used string_concat/3 instead.
main :-
repeat,
read(X),
(
X == end_of_file
;
integer(X),
dart_scores(X,N),
write(N),
fail
).
dart_scores(X,N) :-
concatenate([A1,B1,C1],N),
concatenate(["single", A], A1),
concatenate(["double", B], B1),
concatenate(["triple", C], C1),
find_values(X,A,B,C).
find_values(X,A,B,C) :-
X is A+B*2+C*3,
in_domain(A),
in_domain(B),
in_domain(C).
in_domain(D) :-
integer(D),
D>=1,
20>=D.
concatenate(StringList, StringResult) :-
maplist(atom_chars, StringList, Lists),
append(Lists, List),
atom_chars(StringResult, List).
The error you have has nothing to with string concatenation. I have modified your find_values and in_domain predicate to get rid of the error. The problem with your in_domain predicate is that it does not "generate" integers. As for the find_values predicate, you need to unify first A, B, and C with some integers before checking X is A+B*2+C*3, and generate integer for "single", "double", and "triple". Hope this will help you!
main :-
repeat,
read(X),
(
X == end_of_file
;
integer(X),
dart_scores(X,N),
write(N) /*,
fail */
).
dart_scores(R,N) :-
find_values(R,A,B,C,X,Y,Z),
mult(X, A1),
mult(Y, B1),
mult(Z, C1),
concatenate([A1,A], A2),
concatenate([B1,B], B2),
concatenate([C1,C], C2),
concatenate([A2,B2,C2],N).
mult(1, "single").
mult(2, "double").
mult(3, "triple").
find_values(R,A,B,C,X,Y,Z) :-
in_domain(A),
in_domain(B),
in_domain(C),
range(X,1,3),
range(Y,1,3),
range(Z,1,3),
R is A*X+B*Y+C*Z.
in_domain(D) :-
range(D, 1, 20).
range(Low, Low, _).
range(Out, Low, High) :- NewLow is Low+1, NewLow =< High, range(Out, NewLow, High).
concatenate(StringList, StringResult) :-
maplist(atom_chars, StringList, Lists),
append(Lists, List),
atom_chars(StringResult, List).

Select from subquery and join on subquery in Esqueleto

How can I do select ... from (select ...) join (select ...) in Esqueleto?
I'm aware that I can use rawSql from Persistent, but I'd like to avoid that.
For the record, here is the full query:
select q.uuid, q.upvotes, q.downvotes, count(a.parent_uuid), max(a.isAccepted) as hasAccepted
from
(select post.uuid, post.title, sum(case when (vote.type = 2) then 1 else 0 end) as upvotes, sum(case when (vote.type = 3) then 1 else 0 end) as downvotes
from post left outer join vote on post.uuid = vote.post_id
where post.parent_uuid is null
group by post.uuid
order by post.created_on desc
) q
left outer join
(select post.parent_uuid, max(case when (vote.type = 1) then 1 else 0 end) as isAccepted
from post left outer join vote on post.uuid = vote.post_id
where post.parent_uuid is not null
group by post.id
) a
on a.parent_uuid = q.uuid
group by q.uuid
limit 10
I got here because I had the same question. I imagine the thing we want would be something like:
fromSelect
:: ( Database.Esqueleto.Internal.Language.From query expr backend a
, Database.Esqueleto.Internal.Language.From query expr backend b
)
=> (a -> query b)
-> (b -> query c)
-> query c
Unfortunately, from looking at Database.Esqueleto.Internal.Sql.FromClause:
-- | A part of a #FROM# clause.
data FromClause =
FromStart Ident EntityDef
| FromJoin FromClause JoinKind FromClause (Maybe (SqlExpr (Value Bool)))
| OnClause (SqlExpr (Value Bool))
I don't think there's any support for this in Esqueleto. It only seems to support simple table names and joins with on-clauses that have a boolean expression. I imagine the hardest part of adding support for this is handling table and column name aliases (as sql clause), since ^. expects an expr (Entity val) and an EntityField val typ. Simplest way is to change that to using String or Text for both operands, but that's not very type-safe. I'm not sure what the best option would be implementation-wise to make that type safe.
EDIT: Probably best to forget ^. and have fromSelect generate the aliases when providing the returned values of its first parameter as the arguments of its second parameter. Types would probably have to be altered to make room for these aliases. This is only contemplating from subqueries, not joins. That's another problem.

Suffix array beginning using scala

Today I am trying to create suffix arrays using scala. I was able to do it with massive lines of code but then I heard that it can be created by using only few lines by using zipping and sorting.
The problem I have at the moment is with the beginning. I tried using binary search and zipWithIndex to create the following "tree" but so far I haven't been able to create anything. I don't even know if it is possible by only using a line but I bet it is lol.
What I want to do is to get from a word "cheesecake" is a Seq:
Seq((cheesecake, 0),
(heesecake, 1),
(eesecake, 2),
(esecake, 3),
(secake, 4),
(ecake, 5),
(cake, 6),
(ake, 7),
(ke, 8),
(e, 9))
Could someone nudge me to the correct path ?
To generate all the possible postfixes of a String (or any other scala.collection.TraversableLike) you can simply use the tails method:
scala> "cheesecake".tails.toList
res25: List[String] = List(cheesecake, heesecake, eesecake, esecake, secake, ecake, cake, ake, ke, e, "")
If you need the indexes, then you can use GenIterable.zipWithIndex:
scala> "cheesecake".tails.toList.zipWithIndex
res0: List[(String, Int)] = List((cheesecake,0), (heesecake,1), (eesecake,2), (esecake,3), (secake,4), (ecake,5), (cake,6), (ake,7), (ke,8), (e,9), ("",10))
You're looking for the .scan methods, specifically .scanRight (since you want to start build from the end (ie right-side) of the string, prepending the next character (look at your pyramide bottom to top)).
Quoting the documentation :
Produces a collection containing cumulative results of applying the
operator going right to left.
Here the operator is :
Prepend the current character
Decrement the counter (since your first element is "cheesecake".length, counting down)
So :
scala> s.scanRight (List[(String, Int)]())
{ case (char, (stringAcc, count)::tl) => (char + stringAcc, count-1)::tl
case (c, Nil) => List((c.toString, s.length-1))
}
.dropRight(1)
.map(_.head)
res12: scala.collection.immutable.IndexedSeq[List[(String, Int)]] =
Vector((cheesecake,0),
(heesecake,1),
(eesecake,2),
(esecake,3),
(secake,4),
(ecake,5),
(cake,6),
(ake,7),
(ke,8),
(e,9)
)
The dropRight(0) at the end is to remove the (List[(String, Int)]()) (the first argument), which serves as the first element on which to start building (you could pass the last e of your string and iterate on cheesecak, but I find it easier to do it this way).
One approach,
"cheesecake".reverse.inits.map(_.reverse).zipWithIndex.toArray
Scala strings are equipped with ordered collections methods such as reverse and inits, the latter delivers a collection of strings where each string has dropped the latest character.
EDIT - From a previous suffix question that I posted (from an Purely Functional Data Structures exercise, I believe that suffix should/may include the empty list too, i.e. "" for String.
scala> def suffix(x: String): List[String] = x.toList match {
| case Nil => Nil
| case xxs # (_ :: xs) => xxs.mkString :: suffix(xs.mkString)
| }
suffix: (x: String)List[String]
scala> def f(x: String): List[(String, Int)] = suffix(x).zipWithIndex
f: (x: String)List[(String, Int)]
Test
scala> f("cheesecake")
res10: List[(String, Int)] = List((cheesecake,0), (heesecake,1), (eesecake,2),
(esecake,3), (secake,4), (ecake,5), (cake,6), (ake,7), (ke,8), (e,9))

Pattern Matching different inputs in Haskell

Sorry, this may seem similar to an earlier question but I am still a little confused. Here is the same code I am using as an example:
type Pig = String
type Lion = String
type Feed = [(Char,Char)]
type Visitors = [(Char,Char)]
type Costs = (Int,Int,Int)
data AnimalHome = Farm Pig Pig Pig Feed | Zoo Lion Lion Lion Feed Visitors
orders :: Char -> AnimalHome -> Costs -> Char
orders stuff (Farm p1 p2 p3 feed) (cost1,cost2,cost3) = some code here
But this time I want to execute different functions if the costs are different i.e. (1,3,9) executes a different equation to (0,0,16) etc.
You can adapt the answers to your previos similar questions for this case. Remember that a 3-tuple or triple (i.e. your type Costs) is just another data type. If there were no tuples in Haskell, you could write:
data Triple a b c = Triple a b c
and it would behave exactly as 3-tuples do! The only difference is that Hakell supports a more convenient syntax both for tuple expressions and tuple patterns.
Now for Patterns in general: Simplifying a bit, there are basicall 3 possibilities to write them:
a literal (suitable only for data types that support this, like String, Int, etc.), matches only that value.
a variable, matches any value
a data constructor, applied to patterns. Matches values constructed with that data constructor where the subpatterns match.
Turns out that you already wrote correct patterns in your question:
i.e. (1,3,9) executes a different equation to (0,0,16)
hence
orders stuff (Farm p1 p2 p3 feed) (1,3,9) = some code here
orders stuff (Farm p1 p2 p3 feed) (0,0,16) = some other code here
It probably would help us to help you if we could understand what your specific issues with pattern matching is. i.e. why you couldn't just try to come up with that yourself, as it feels quite natural, does it not?
If you really mean to use different functions with different integers, it's fine to use pattern matching
orders stuff (Farm p1 p2 p3 feed) (1,3,9) = -- one thing
orders stuff (Farm p1 p2 p3 feed) (0,0,16) = -- another thing
but I'd only really use that with 0, not other values. Really what you're after is called guards:
orders stuff (Farm p1 p2 p3 feed) (a,b,c)
| a == 0 && b == 0 = -- one thing
| a*b^2=c = -- another thing
| b < 0 = -- a third thing
and each condition is checked in turn - only the first true condition gets to run its code.

Prolog: how to convert string to integer?

So as the title says - how do you convert a string into an integer?
the idea is something like this:
convert(String,Integer).
examples:
convert('1',1).
convert('33',33).
I'm using swi prolog
Use atom_number/2.
E.g:
atom_number('123', X).
X = 123.
Assuming you really meant a string and not an atom, use number_codes.
?- number_codes(11, "11").
true.
?- number_codes(11, Str).
Str = [49, 49]. % ASCII/UTF-8
?- number_codes(N, "11").
N = 11.
Perhaps use of atom_codes(?Atom, ?String) and number_chars(?Number, ?CharList) would do it.
Quite an old, but there is a predicate in SWI Prolog: number_string(N, S).
Docs
number_string(123, S).
S = "123".
For those who are still looking for it.
A simple example using Visual Prolog 10
==============================
% UNS-EPISI-LAB-IA
implement main
open core
clauses
run() :-
console::write("Valor de A? "),
A = console::readLine(),
console::write("Valor de B? "),
B = console::readLine(),
Areal = toTerm(real, A),
Breal = toTerm(real, B),
console::write("A + B = ", Areal + Breal),
_ = console::readChar().
end implement main
goal
console::runUtf8(main::run).
in Visual Prolog convert:
X=toTerm(real,H).
real/integer/unsigned...

Resources