I have this list:
ADD X
ADD Y
REMOVE Z
ADD X
NO ACTION Y
I need of this results:
ADD X
NO ACTION Y
REMOVE Z
The rules to calculate the delta are these:
I have 3 action (ADD, REMOVE, NO ACTION)
ANY ACTION * NO ACTION = NO ACTION
ADD * REMOVE or REMOVE * ADD = NO ACTION
SAME ACTION * SAME ACTION = SAME ACTION
The problem is that I implement this with a functional language (XQuery). I found a logic, based on fn:distinct-values. But the last rule (3) is unsatisfied.
Thanks in advance!!
You didn't mention what XQuery processor you are using, but if it has hashmaps, you can do it this way (tested in MarkLogic Server):
let $seq := ("ADD X", "ADD Y", "REMOVE Z", "ADD X", "NO-ACTION Y")
let $map := map:map()
let $_ :=
for $s in $seq
let $parts := fn:tokenize($s, " ")
let $service := $parts[2]
let $action := $parts[1]
let $current-action := map:get($map, $service)
return
if ("NO-ACTION" = ($action, $current-action)) then
map:put($map, $service, "NO-ACTION") (: rule 1 :)
else if ("REMOVE" = ($action, $current-action)) then
map:put($map, $service, "REMOVE") (: rule 2 :)
else
map:put($map, $service, $action) (: actions are the same -- rule 3 :)
for $service in map:keys($map)
return fn:concat(map:get($map, $service), " ", $service)
Returns
ADD X
REMOVE Z
NO-ACTION Y
Note that I made a simplifying assumption and changed "NO ACTION" to "NO-ACTION" to make the parsing simpler.
Finally I found the way. I hope that this is good.
These are my first experiments with XQuery and I need to remeber what I have under my fingers and what possibilities this language offer.
My problem is data that came in. And I decide to transformate the information in a structure that can I easily manipulate.
A golden brick to solve this is this example about grouping data :
for $d in distinct-values(doc("order.xml")//item/#dept)
let $items := doc("order.xml")//item[#dept = $d]
order by $d
return <department code="{$d}">{
for $i in $items
order by $i/#num
return $i
}</department>
After this I used this algorithm:
0. If the count of action == 1 -> take first action
1. else If exist almost ONE - NO ACTION -> NO ACTION (RULE 1)
2. else If exist ADD and REMOVE in same list -> NO ACTION (RULE 2)
3. else take the first action (equal actions)
For this I borrowed a function from functx library:
declare function local:is-value-in-sequence( $value as xs:anyAtomicType? ,$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
};
Simple but effective.
Thanks a lot for all!
Related
Simple code there-
let $sV2 :=''
for $i in (1 to 2)
let $sV1 := 'test1'
let $sV2 := if (fn:string-length($sV2) != 0) then fn:concat($sV2,'||',$sV1) else ($sV1)
return
<test>{$sV2}</test>
i get the same output
<test>test1</test>
<test>test1</test>
whereas i expect
<test>test1</test>
<test>test1||test1</test>
what am i doing wrong? i tried to debug but why does V2 initialize to null/'' for second iteration.
Note- I have to use xquery 1.0 do to some product limitations.
How do i get the expected output?
XQuery is a functional language. As such, it does not allow you to change the value of a variable once it has been assigned.
There are many other ways to reach the same results, though. Your specific query can e.g. be rewritten as follows:
for $i in 1 to 2
return <test>{
string-join(for $n in 1 to $i return 'test1', '||')
}</test>
initlNum453 = List[];
num1 = 2;
(*Pt1, initial work to make initlNum full of good variables*)
algorithmicNum = 1;
For[i7 = 1, i7 <= (num1 + 1)^2, i7++,
AppendTo[initlNum453, algorithmicNum];
If[((algorithmicNum) == (num1 + 1)), algorithmicNum = 1,
algorithmicNum++];
];
(*Pt2, delete unneeded variables*)
deleteValue = 1;
Do[
Delete[initlNum453, deleteValue];
deleteValue = (deleteValue + num1 + 2);
, {num1 + 1}
]
Here's a snippet of the code I'm trying to make (it involves pseudo-automating Lagrange polynomials). It should be simple; the first part creates a series of numbers in a list, and then the second should be delete a particular section (e.g., the 1,4,7 if n=2).
For some reason, one of the following occurs:
No Error, but the elements in the list remains the same/no elements get deleted
Taking out the semicolon says that the "Tag Times in ___ is Protected"-- can someone explain what exactly this means?
When putting this into a Module, the error states that the expression .' cannot be used as a part specification. Use Key[.`] instead.
In any case, I don't understand why something as simple as this is just doesn't work on Mathematica. The "Delete" function works outside of a for/do loop, but doesn't inside-- can someone explain why or tell me what I did wrong?
Thanks for your help! I appreciate it!
You need to write something like
initlNum453 = Delete[initlNum453, deleteValue]
I'm interested if there's a package in R to support call-chain style data manipulation, like in C#/LINQ, F#?
I want to enable style like this:
var list = new[] {1,5,10,12,1};
var newList = list
.Where(x => x > 5)
.GroupBy(x => x%2)
.OrderBy(x => x.Key.ToString())
.Select(x => "Group: " + x.Key)
.ToArray();
I don't know of one, but here's the start of what it could look like:
`%then%` = function(x, body) {
x = substitute(x)
fl = as.list(substitute(body))
car = fl[[1L]]
cdr = {
if (length(fl) == 1)
list()
else
fl[-1L]
}
combined = as.call(
c(list(car, x), cdr)
)
eval(combined, parent.frame())
}
df = data.frame(x = 1:7)
df %then% subset(x > 2) %then% print
This prints
x
3 3
4 4
5 5
6 6
7 7
If you keep using hacks like that it should be pretty simple to get the kind of
syntax you find pleasing ;-)
edit: combined with plyr, this becomes not bad at all:
(data.frame(
x = c(1, 1, 1, 2, 2, 2),
y = runif(6)
)
%then% subset(y > 0.2)
%then% ddply(.(x), summarize,
ysum = sum(y),
ycount = length(y)
)
%then% print
)
dplyr chaining syntax resembles LINQ (stock example):
flights %>%
group_by(year, month, day) %>%
select(arr_delay, dep_delay) %>%
summarise(
arr = mean(arr_delay, na.rm = TRUE),
dep = mean(dep_delay, na.rm = TRUE)
) %>%
filter(arr > 30 | dep > 30)
Introduction to dplyr - Chaining
(Not an answer. More an extended comment on Owen's answer.] Owen's answer helped me understand what you were after and I thoroughly enjoyed reading his insightful answer. This "outside to inside" style reminded me of an example on the help(Reduce) page where the Funcall function is defined and then successively applied:
## Iterative function application:
Funcall <- function(f, ...) f(...)
## Compute log(exp(acos(cos(0))
Reduce(Funcall, list(log, exp, acos, cos), 0, right = TRUE)
What I find especially intriguing about Owen's macro is that it essentially redefines the argument processing of existing functions. I tried thinking of how I might provide arguments to the "interior" functions for the Funcall aproach and then realized that his %then% function had already sorted that task out. He was using the function names without their leftmost arguments but with all their other right-hand arguments. Brilliant!
https://github.com/slycoder/Rpipe
c(1,1,1,6,4,3) %|% sort() %|% unique()
# result => c(1,3,4)
Admittedly, it would be nice to have a where function here, or alternatively to allow anonymous functions to be passed in, but hey the source code is there: fork it and add it if you want.
I have a very simple question. I'd like to use a where clause after a bloc of code that uses bind operators but I get a compilation error.
Here is a simple example:
main =
putStrLn "where clause test:" >>
return [1..10] >>= \list ->
print list'
where list' = reverse list -- test1.hs:5:28: Not in scope: `list'
I can use a let clause for list' as in
main =
putStrLn "where clause test:" >>
return [1..10] >>= \list ->
let list' = reverse list -- works of course
in print list'
but I'd really like it if I could use a where clause...
I also tried with do notation
main = do
putStrLn "where clause test:"
list <- return [1..10]
print list'
where list' = reverse list --test3.hs:5:30: Not in scope: `list'
Same problem. Can I use a where clause in these circumstances?
As ephemient explains, you can't use where clauses the way you do.
The error happens because in this code:
main =
return [1..10] >>= \list ->
print list'
where
list' = reverse list
The where-clause is attached to the main function.
Here's that same function with more parentheses:
main = return [1..10] >>= (\list -> print list')
where
list' = reverse list
I think its fairly obvious why you get the "out of scope" error: The binding for list is deep inside the main expression, not something the where clause can reach.
What I usually do in this situation (and I've been bitten by the same thing a bunch of times). I simply introduce a function and pass the list as an argument.
main = do
list <- return [1..10]
let list' = f list
print list'
where
f list = reverse list -- Consider renaming list,
-- or writing in point-free style
Of course, I imagine your actual code in the f function is a lot more that just reverse and that's why you want it inside a where clause, instead of an inline let binding. If the code inside the f function is very small, I'd just write it inside the let binding, and wouldn't go through the overhead of introducing a new function.
The problem is that let-in is an expression, which can be used inside other expressions, while where can only be used on a (module|class|instance|GADT|...) declaration or a (function|pattern) binding.
From the Haskell 98 report on declarations and bindings,
p | g1 = e1
| g2 = e2
…
| gm = em
where { decls }
is sugar for
p = let decls in
if g1 then e1 else
if g2 then e2 else
…
if gm then em else error "Unmatched pattern"
or, simplifying things by removing guards,
p = e where { decls }
is sugar for
p = let decls in e
in both function and pattern bindings. This is true even when your e is a do {…} construct.
If you want to have a binding local to a particular subexpression within a larger expression, you need to use let-in (or simply let inside a do, but that's just sugar for let-in).
You can't even write
main = do
putStrLn "where clause test: "
list <- return [1..10]
(print list' where list' = reverse list)
because "e where { decls }" is not a legal expression – where can only be used in declarations and bindings.
main = do
putStrLn "where clause test: "
list <- return [1..10]
let list' = list'' where list'' = reverse list
print list'
This is legal (if somewhat contrived).
As far as I can tell, the where clause is only used in local bindings. The inner part of a >>(=) binding statement is not a local binding (two different kinds of bindings in that sentence).
Compare with this:
main = f [1..10]
f list =
putStrLn "where clause test:" >> print list'
where list' = reverse list
You might want to refer to the Haskell 98 syntax report - not sure how much help it would be.
If I'm wrong, someone will certainly correct me, but I'm pretty sure you can't use a where clause at all in the style you've shown above. list will never be in scope to a where clause unless it's a parameter to the function.
I came across this subject when I was reading through PrototypeJS's docs: its Identity Function. I did some further searching&reading on it and I think I understand its mathematical basis (e.g. multiplication by 1 is an identity function (or did I misinterpret this?)), but not why you would write a JS(or PHP or C or whatever)-function that basically takes X as a parameter and then just does something like return X.
Is there a deeper insight connected to this? Why does Prototype supply this function? What can I use it for?
Thanks :)
Using the Identity function makes the library code slightly easier to read. Take the Enumerable#any method:
any: function(iterator, context) {
iterator = iterator || Prototype.K;
var result = false;
this.each(function(value, index) {
if (result = !!iterator.call(context, value, index))
throw $break;
});
return result;
},
It allows you to check if any of the elements of an array are true in a boolean context. Like so:
$A([true, false, true]).any() == true
but it also allows you to process each of the elements before checking for true:
$A([1,2,3,4]).any(function(e) { return e > 2; }) == true
Now without the identity function you would have to write two versions of any function, one if you pre process and one if you dont.
any_no_process: function(iterator, context) {
var result = false;
this.each(function(value, index) {
if (value)
throw $break;
});
return result;
},
any_process: function(iterator, context) {
return this.map(iterator).any();
},
I do not know about that library, but normally, you optimize formuals or code or whatever by factoring common part out, like if (add) (a + b) + x else a + b should be rewritten into a + b + (add ? x : 0). You are tempted to do the same with
if (!initialized) initialize(callback_with_very_long_name) else callback_with_very_long_name
Looks pretty similar. You can easily factor out a common factor or term but how do we factor out a function application? If you understand mathematiscs or Hascel, you should see that
a ? x + v : v
looks very much like
a ? f value : value
You add x in one case but not in the other. You apply function in one case but not in the other. You optimize the former into (a ? x : 0) + v because 0 is additive identity (it does not change anything when added to it) and v is a common factor here, which comes always, regardless of application of x. In case of function application (or not application), the callback is the common factor. We want to factor it out. What is the identity function that we should apply to it so that nothing changes? Identity function!
(a ? f : identity) value
is what we are looking for. Our original example looks like the following then
(initialized ? identity : initialize) (callback_with_very_long_name)
Please note that it fits into one row of page now.