据我所知,sDiff只适用于套装。 但是如何在索引列表之间进行区分?
....
$Redis->lPush("KEY1", "Value1");
$Redis->lPush("KEY1", "Value2");
$Redis->lPush("KEY1", "Value3");
$Redis->lPush("KEY2", "Value1");
$Redis->lPush("KEY2", "Value3");
$Redis->lPush("KEY2", "Value4");
$Redis->sDiff("KEY1", "KEY2");
....
答案 0 :(得分:2)
没有内置命令 - 您可以选择拉出两个列表并在客户端中执行比较(for diff),或者编写一个使用EVAL
命令运行的Lua脚本执行服务器端。以下是此类脚本的示例:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
</head>
<body>
<script>
var candleWidth = 20;
var candleGap = 40;
var candleMargin = 10;
var wickThickness = "2";
var hLineColor = "#b5b6b7";
var margin = {top: 20, right: 20, bottom: 20, left: 60},
width = 600 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var data = [{
Date: 01 / 12 / 15,
High: 118.81,
Low: 116.86,
Open: 118.75,
Close: 117.34
}, {
Date: 02 / 12 / 15,
High: 118.11,
Low: 116.08,
Open: 117.05,
Close: 116.28
}, {
Date: 03 / 12 / 15,
High: 116.79,
Low: 114.22,
Open: 116.55,
Close: 115.2
}, {
Date: 04 / 12 / 15,
High: 119.25,
Low: 115.11,
Open: 115.29,
Close: 119.03
}, {
Date: 07 / 12 / 15,
High: 119.86,
Low: 117.81,
Open: 118.98,
Close: 118.28
}, {
Date: 05 / 01 / 16,
High: 105.85,
Low: 102.41,
Open: 105.75,
Close: 102.71
}, {
Date: 04 / 02 / 16,
High: 97.33,
Low: 95.19,
Open: 95.86,
Close: 96.6
}, {
Date: 01 / 12 / 15,
High: 118.81,
Low: 116.86,
Open: 118.75,
Close: 117.34
}, {
Date: 02 / 12 / 15,
High: 118.11,
Low: 116.08,
Open: 117.05,
Close: 116.28
}, {
Date: 03 / 12 / 15,
High: 116.79,
Low: 114.22,
Open: 116.55,
Close: 115.2
}, {
Date: 04 / 12 / 15,
High: 119.25,
Low: 115.11,
Open: 115.29,
Close: 119.03
}, {
Date: 07 / 12 / 15,
High: 119.86,
Low: 117.81,
Open: 118.98,
Close: 118.28
}, {
Date: 05 / 01 / 16,
High: 105.85,
Low: 102.41,
Open: 105.75,
Close: 102.71
}, {
Date: 04 / 02 / 16,
High: 97.33,
Low: 95.19,
Open: 95.86,
Close: 96.6
}];
var maxi = d3.max(data, function(d) {
return d.value;
}); // to check what the max value in the data array is ... for info purposes
//console.log(maxi); //not displaying in brackets??
// .map() creates an new array based on function
var maxLow = d3.min(data.map(function(x) {
return x["Low"];
})) // returns the lowest value of 'low'
var maxHigh = d3.max(data.map(function(x) {
return x["High"];
})) // returns the highest value of 'high'
var maxMinDiff = (maxHigh - maxLow) * 0.1;
//console.log(maxMinDiff);
//function that will return the lowest of two numbers a or b
function min(a, b) {
return a < b ? a : b;
};
//function that will return the highest of two number a or b
function max(a, b) {
return a > b ? a : b;
};
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickSize(-height);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5)
.tickSize(-width);
var x = d3.scale.linear().domain([-width / 2, width / 2]).range([0, width]);
//Var Y is a function that will scale the numbers on the Y axis from an input domain into output range; height-0 which inverts or flips Y otherwise visualisation is upside down
var y = d3.scale.linear()
.domain([maxLow - maxMinDiff, maxHigh + maxMinDiff]) //changed to reflect new variables for lowest, highest and difference to define input domain
.range([height, 0]); //range has still not been modified ... remember x,y have been reversed to reflect y,x
//this section is very similar to mashup code at #2
var zoom = d3.behavior.zoom()
.x(x)
.y(y)
.scaleExtent([1, 32])
.on("zoom", zoomed);
var chart = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var grid = chart.append("g")
.attr("class", "gridding");
//script to create horizontal lines for viewing
var lines = grid.selectAll("line.y")
.data(y.ticks(20))
.enter()
.append("svg:line")
.attr("class", "y")
.attr("x1", 0)
.attr("x2", width)
.attr("y1", y)
.attr("y2", y)
.attr("stroke", hLineColor);
var numbers = grid.selectAll("text.yrule")
.data(y.ticks(10))
.enter()
.append("svg:text")
.attr("class", "yrule")
.attr("x", 0)
.attr("y", y)
.attr("dy", 0)
.attr("dx", 20)
.style("fill", "#b5b6b7")
.attr("text-anchor", "middle")
chart.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
chart.append("rect")
.attr("class", "pane")
.attr("width", width)
.attr("height", height)
.call(zoom)
.style("fill","none")
.style("pointer-events", "all");
var candlestick = chart.append("g")
.attr("clip-path", "url(#clip)")
.append("g")
.attr("class", "candlesticks")
//function to build a chart using data in var data
//.call zoom and append g enable pan and zoom ... still not perfect ... don't want y axis moving etc
function buildChart(data) {
//script for creating the candlestick wick that will lie behind the rectangle//x1 y1 represent High and x2 y2 represent Low
//coded first to sit beneath the rectangle
var wicks = candlestick.selectAll("wick")
.data(data)
.enter()
.append("line")
.attr("x1", function(d, i) {
return candleMargin + candleWidth / 2 + (candleGap * i);
})
.attr("x2", function(d, i) {
return candleMargin + candleWidth / 2 + (candleGap * i);
})
.attr("y1", function(d) {
return y(max(d.High, d.Low));
}) //return which ever is highest value H or L using var y for scaling
.attr("y2", function(d) {
return y(min(d.High, d.Low));
}) //return which ever is lowest value H or L using var y for scaling
.attr("stroke", function(d) {
return d.Open > d.Close ? "#a01f1b" : "#1ba048";
})
.attr("stroke-width", wickThickness);
//script for creating rectangle representing Open and Close positions
// chart.selectAll("rect")
var candle = candlestick.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x", function(d, i) {
return candleMargin + (candleGap * i);
})
.attr("y", function(d) {
return y(max(d.Open, d.Close));
}) //top left hand corner of rectangle coordinates
.attr("height", function(d) {
return y(min(d.Open, d.Close)) - y(max(d.Open, d.Close));
})
.attr("width", function(d) {
return candleWidth
})
.attr("fill", function(d) {
return d.Open > d.Close ? "#a01f1b" : "#1ba048";
})
.style("pointer-events", "none");
} //closing brackets for buildChart function
buildChart(data);
function zoomed() {
candlestick.attr("transform", "translate(" + d3.event.translate + ")")
}
</script>
</body>
</html>
使用--[[
LDIFF key [key ...]
Returns the elements in the first list key that are also present in all other
keys.
]]--
-- A utility function that converts an array to a table
local function a2t(a)
local t = {}
for i, v in ipairs(a) do
t[v] = true
end
return t
end
-- A utility function that converts a table to an array
local function t2a(t)
local a = {}
for k, _ in pairs(t) do
a[#a+1] = k
end
return a
end
-- main
local key = table.remove(KEYS,1)
local elems = a2t(redis.call('LRANGE', key, 0, -1))
-- iterate remaining keys
while #KEYS > 0 do
key = table.remove(KEYS,1)
local check = a2t(redis.call('LRANGE', key, 0, -1))
-- check each element in the current key for existence in the first key
for k, _ in pairs(elems) do
if check[k] then
elems[k] = nil
end
end
end
-- convert the table to an array and reply
return t2a(elems)
运行此代码如下:
redis-cli
答案 1 :(得分:0)
Redis没有内置支持来查找列表差异。但有一个解决方法。通过查看代码的语法,我假设您正在使用php。 PHP array_diff()是要救援的。以下步骤应该有效。
$a1 = $Redis->lPush("KEY1",0,-1)
$a2 = $Redis->lPush("KEY2",0,-1)
diff = array_diff($a1,$a2)
这种方法可以翻译成任何其他编程语言。
P.S。如果列表很大,请确保您获得批量差异,而不是一次加载所有项目。