两个名单之间的Redis差异?

时间:2017-01-14 15:23:59

标签: php redis

据我所知,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");
....

2 个答案:

答案 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。如果列表很大,请确保您获得批量差异,而不是一次加载所有项目。