Related
This question is resulting from a previous question here
Lets says our implemented server v1 and v2 response looks as follows
* def v1Response = { id: "1", name: "awesome" }
* def v2Response = { id: "2", name: "awesome", value: "karate" }
Similarly we define the client schema for v1 and v2 like as follows
* def v1Schema = { id: "#string", name: "#string }
* def v2Schema = { id: "#string", name: "#string, value: "#string" }
From the above given data, all I want is to test following three cases in a single generic line and they must pass
1. * match v1Response == v1Schema
2. * match v2Response == v2Schema
3. * match v2Response contains v1Schema
using a single generic line as follows
* match response ==/contains schema <--- should be able to test all above three cases above and they must pass.
See my proposed suggestion in previous question for maybe possible ways to achieve this.
I have already tried the solution noted in previous question using karate.filterKeys(), however the third case will fail because it focuses on filtering the keys not the comparison itself so the below last line will not be able to test all three cases above.
* def response = { id: "2", name: "awesome", value: "karate" }
* def schema = { id: "#string", name: "#string" }
* match response == karate.filterKeys(schema, response) <--- This will fail
For an accepted answer all three case must pass
Looks like you over-engineered so much you forgot about contains :P
* def schemas =
"""
{
v1: { id: "#string", name: "#string" },
v2: { id: "#string", name: "#string", value: "#string" }
}
"""
* def env = 'v1'
* def response = { id: "1", name: "awesome" }
* match response contains karate.filterKeys(schemas[env], response)
* def response = { id: "2", name: "awesome", value: "karate" }
* match response contains karate.filterKeys(schemas[env], response)
* def env = 'v2'
* def response = { id: "1", name: "awesome" }
* match response contains karate.filterKeys(schemas[env], response)
* def response = { id: "2", name: "awesome", value: "karate" }
* match response contains karate.filterKeys(schemas[env], response)
I am using apiDoc for documentation in Sails.js app. And, last week I saw someone define responses being used by multiple controllers in a file named api_definitions.js
Example
/*
* #apiDefine UserSuccessExample
* #apiSuccessExample Success-Response:
* HTTP/1.1 201 OK
* {
* "message": "User Created successfully",
* "user" : {
* "displayname": "somedisplayname",
* "lastname": "ALastName",
* "firstname": "AFirstName",
* "email": "sososo#soos.so",
* "phonenumber": "0839293288"
* },
* "token" : "ey.jkernekrerkerkeekwewekwbejwbewbebewbwkebebbwbeibwubfebfebwiee"
* }
*/
And, in each of the controllers, referenced it using the normal Use Parameter #apiUse UserSuccessExample. But when I tried it, I was getting an error in my console saying, it wasn't defined:
Error
error: Referenced groupname does not exist / it is not defined with #apiDefine.
{ File: 'api/controllers/UserController.js',
Block: 2,
Element: '#apiUse',
Groupname: 'UserSuccessExample',
Definition: '#apiUse group',
Example: '#apiDefine MyValidGroup Some title\n#apiUse MyValidGroup' }
I'm sure this function is likely common ( or possibly achievable other ways ) but I'm not sure of what it'd be called. I'm thinking of a sliding window of a certain size :-
let slidingMap = (arr,size, f) => {
r = []
arr.reduce((acc, n) => {
let b = acc.concat(n);
if(b.length > size) {
b.shift();
}
if(b.length == size) {
r.push(f(b))
}
return b;
},[])
return r;
}
so given slidingMap([1,2,3,4,5,6], 2, b => b)
you'd get [ [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 4, 5 ], [ 5, 6 ] ]
and slidingMap([1,2,3,4,5,6], 3, b => b)
you'd get [ [ 1, 2, 3 ], [ 2, 3, 4 ], [ 3, 4, 5 ], [ 4, 5, 6 ] ]
or for calculating differences :-
slidingMap([1,2,3,7,5,6],2, b => b.reduceRight((a, n) => a? a-n : n))
you'd get [ 1, 1, 4, -2, 1 ]
or moving average :-
slidingMap([1,2,3,7,5,6],3, b => b.reduce((a, n) => a+n,0)/b.length)
you'd get [ 2, 4, 5, 6 ]
so, is there a commonly implemented function(s) that achieves this?
Update
Probablly better implemented as
let sliding = (arr,size) => {
r = []
arr.reduce((acc, n) => {
let b = acc.concat(n);
if(b.length > size) {
b.shift();
}
if(b.length == size) {
r.push(b)
}
return b;
},[])
return r;
}
then just use map
sliding([1,2,3,4,5],2).map(somefunc);
Or perhaps using zip and skip ( using lodash in this case )
let sliding = (arr, size) =>
_.zip(..._.range(size).map(i => arr.slice(i)))
.filter(a => !a.some(v => v == undefined))
only trick here is the zip will insert undefined when it has no match so they need to be filtered out.
Does anybody know how can I get members with scores by node redis?
I tried something like this:
client.ZRANGE(key, 0, -1, withscores, function(err, replies) {
});
Thanks.
This code looks good. Check out the following link for retrieving what you want :
http://ricochen.wordpress.com/2012/02/28/example-sorted-set-functions-with-node-js-redis/
Added the code here from that link example in case it is ever removed.
var rc=require('redis').createClient();
var _=require('underscore');
rc.zincrby('myset', 1, 'usera');
rc.zincrby('myset', 5, 'userb');
rc.zincrby('myset', 3, 'userc');
rc.zrevrange('myset', 0, -1, 'withscores', function(err, members) {
// the resulting members would be something like
// ['userb', '5', 'userc', '3', 'usera', '1']
// use the following trick to convert to
// [ [ 'userb', '5' ], [ 'userc', '3' ], [ 'usera', '1' ] ]
// learned the trick from
// http://stackoverflow.com/questions/8566667/split-javascript-array-in-chunks-using-underscore-js
var lists=_.groupBy(members, function(a,b) {
return Math.floor(b/2);
});
console.log( _.toArray(lists) );
});
rc.quit();
Seems your code is right. The following is the syntax to get zrange.
without score:
redisClient.zrange(keyName,start,stop,function(err,result){
//result is array
// every index will give you member name
})
Ex :
redisClient.zrange("mySortedset",-1,-1,function(err,result){
//result is array
// every index will give you member name
})
with score:
redisClient.zrange(keyName,start,stop,'withscores',function(err,result){
//result is array
// here even index will hold member
// odd index will hold its score
})
Ex :
redisClient.zrange("mySortedset",-1,-1,'withscores',function(err,result){
//result is array
// here even index will hold member
// odd index will hold its score
})
I tried with the prior accepted answers but i could not get the result i want and later i tried with the following code and got appropriate result,
Original output:
[ 'player:522',
'19685',
'player:164',
'19594',
'player:807',
'19171',
'player:694',
'19165',
'player:905',
'19108',
'player:859',
'19087',
'player:432',
'18973',
'player:515',
'18831',
'player:163',
'18750',
'player:4',
'18552' ]
Expected output:
{
"player:522": "19685",
"player:164": "19594",
"player:807": "19171",
"player:694": "19165",
"player:905": "19108",
"player:859": "19087",
"player:432": "18973",
"player:515": "18831",
"player:163": "18750",
"player:4": "18552"
}
Solution:
redisClient.ZREVRANGE('daily', 1, 10, 'WITHSCORES', function(err, result) {
result = _.fromPairs(_.chunk(result, 2));
return res.status(200).json(result);
});
The right approach for versions ^2.0,
var args = [ key,to, from ];
redisClient.zrevrangebyscore(args,function(err,data){
Vanilla JS Solution
Redis call:
redisClient.zrange(keyName, start, stop, 'withscores', function(err, result) {
// result.reduce ... (See below)
}
Here is a Vanilla-JS solution that I came up with pretty quickly.
For me, personally, it does not make sense to import underscore or any other library to perform such an easy task:
result.reduce(function (a, c, i) {
var idx = i / 2 | 0;
if (i % 2) {
a[idx].score = c;
} else {
a[idx] = { id: c };
}
return a;
}, []);
Assuming this input:
['player1', 13, 'player2', 11, 'player4', 7, 'player3', 3, 'player5', 0]
This function yields:
[
{ id: 'player1', score: 13 },
{ id: 'player2', score: 11 },
{ id: 'player4', score: 7 },
{ id: 'player3', score: 3 },
{ id: 'player5', score: 0 }
]
Here is another one to transform the result into a two-dimensional array:
result.reduce(function (a, c, i) {
var idx = i / 2 | 0;
if (i % 2) {
a[idx].push(c);
} else {
a[idx] = [c];
}
return a;
}, []);
which produces the following array:
[
[ 'player1', 13 ],
[ 'player2', 11 ],
[ 'player4', 7 ],
[ 'player3', 3 ],
[ 'player5', 0 ]
]
One line lambda version:
result.reduce((a, c, i) => i % 2 ? (a[i / 2 | 0].data = c, a) : (a[i / 2 | 0] = { id: c }, a), []);
Vanilla JS reduce works well here.
const result = [
'player:522',
'19685',
'player:164',
'19594',
'player:807',
'19171',
'player:694',
'19165',
'player:905',
'19108',
'player:859',
'19087',
'player:432',
'18973',
'player:515',
'18831',
'player:163',
'18750',
'player:4',
'18552'
]
const map = result.reduce((map, k, i, res) => {
if (i % 2 !== 0) {
map[res[i - 1]] = Number(k);
}
return map;
}, {})
map is now:
{
'player:522': 19685,
'player:164': 19594,
'player:807': 19171,
'player:694': 19165,
'player:905': 19108,
'player:859': 19087,
'player:432': 18973,
'player:515': 18831,
'player:163': 18750.65468,
'player:4': 18552
}
var data = []
results.map((result, index) => {
if (index % 2 == 0) {
data.push(results[index] = { player: results[index], score: results[index+1] })
}
})
console.log(data)
I have the following collection of nodes and edges. What I want to do is to find all the distinct graph from it.
my %connections=(36=>[31],10=>[3,4],31=>[30,22],30=>[20],22=>[20,8],20=>[1],8=>[5],5=>[2],2=>[1,20], 3=>[7]);
In this example it will yield:
my %all_graph = {
graph1 => {36=>[31],31=>[30,22],30=>[20],22=>[20,8],20=>[1],8=>[5],5=>[2],2=>[1,20]}.
graph2 => {10=>[3,4], 3=>[7]}
};
Is there any existing algorithms that does that?
Use the Graph module:
#!/usr/bin/perl
use strict; use warnings;
use Graph;
my %connections = (
36 => [ 31 ],
10 => [ 3, 4],
31 => [ 30, 22],
30 => [ 20 ],
22 => [ 20, 8],
20 => [ 1 ],
8 => [ 5 ],
5 => [ 2 ],
2 => [ 1, 20 ],
3 => [ 7 ]
);
my $g = Graph->new( undirected => 1 );
for my $src ( keys %connections ) {
for my $tgt ( #{ $connections{$src} } ) {
$g->add_edge($src, $tgt);
}
}
my #subgraphs = $g->connected_components;
my #allgraphs;
for my $subgraph ( #subgraphs ) {
push #allgraphs, {};
for my $node ( #$subgraph ) {
if ( exists $connections{ $node } ) {
$allgraphs[-1]{$node} = [ #{ $connections{$node} } ];
}
}
}
use YAML; print Dump \#allgraphs;
Output:
[sinan#archardy SO]$ ./g
---
- 2:
- 1
- 20
20:
- 1
22:
- 20
- 8
30:
- 20
31:
- 30
- 22
36:
- 31
5:
- 2
8:
- 5
- 10:
- 3
- 4
3:
- 7
To find the connected components of an undirected graph you just do a BFS or DFS (Breadth/Depth first search).
Here some sample BFS code
my %connections=(36=>[31],10=>[3,4],31=>[30,22],30=>[20],22=>[20,8]
,20=>[1],8=>[5],5=>[2],2=>[1,20], 3=>[7]);
my $full_connections = {}; # Build a REAL graph with full 2-way edge lists
foreach my $node (keys %connections) {
foreach my $node2 (#{ $connections{$node} }) {
print "$node, $node2\n";
$full_connections->{$node}->{$node2} = 1;
$full_connections->{$node2}->{$node} = 1;
}
}
my %all_graph = ();
my $current_graph = 0;
my %visited = ();
my #to_visit = ();
foreach my $node (keys %$full_connections) {
next if exists $visited{$node};
# start the next segment
$current_graph++;
#to_visit=($node);
while (#to_visit) {
$node_to_visit = shift #to_visit;
#next if $visited{$node_to_visit};
$visited{$node_to_visit} = $current_graph;
push #to_visit, grep { !exists $visited{$_} }
keys %{ $full_connections->{$node_to_visit} };
}
}
# Now reconstruct %all_graph from %visited - left as exercise for the reader
print Data::Dumper->Dump([\%visited]);
I'd suggest the following algorithm:
1.) Move all nodes into a working set N.
2.) Starting with an arbitrary node perform a graph search (depth-first or breadth-first). Add all visited nodes and edges to the first subgraph, remove visited nodes from N
3.) If N is non-empty, select the next starting node and go to step 2.) for the next subgraph.