URLのパラメータ差分を取る

いらなくなった...

いちおう /page/1 みたいなURLでページングしてるやつに対しても機能するかも。
日付でページングしてるやつに対しては無力。20071231 -> 20080101 の差分がふつうに8870になるので次とみなされない。単体で使うには単純すぎて無理。

//
// diff_onp and snake from
// Javascriptでdiffる ( with 形態素解析 ) (nakatani @ cybozu labs) http://labs.cybozu.co.jp/blog/nakatani/2007/06/javascriptdiff_with.html
//
 function 
diff_onp(a, b, del, ins) {
  var m = a.length, n = b.length;
  var delta = n - m;
  var fp=[],lst=[], path=[]
//  var snake 
  for(var i=-m-1;i<=n+1;i++) { fp[i]=-1; lst[i]=-1; }
  for(var p=0;p<=m;p++) {
    for(var k=-p;k<delta;k++) {
      snake(fp, lst, path, k, a, b, m, n);
    }
    for(var k=delta+p;k>delta;k--) {
      snake(fp, lst, path, k, a, b, m, n);
    }
    snake(fp, lst, path, delta, a, b, m, n);
    if (fp[delta] >= n) {
      var pt = lst[delta];
      list = []
      while (pt>=0) {
        var buf = eval("["+path[pt]+"]");
        list.push([buf[1], buf[2]]);
        pt = buf[0];
      }
      var x0 = 0, y0 = 0;
      var result = [];
      for(var i=list.length-1;i>=0;i--) {
        var x1 = list[i][0], y1 = list[i][1];
        while (x0<x1 || y0<y1) {
          if (y1-x1 > y0-x0) {
            result.push({item:b[y0++], command:ins});
          } else if (y1-x1 < y0-x0) {
            result.push({item:a[x0++], command:del});
          } else {
            result.push({item:a[x0++], command:'common'});
            y0++;
          }
        }
      }
      return result;
    }
  }
}

 function snake(fp, lst, path, k, a, b, m, n) {
  var y = fp[k-1]+1, pre;
  if (y > fp[k+1]) {
    pre = lst[k-1];
  } else {
    y = fp[k+1];
    pre = lst[k+1];
  }
  var x = y - k;
  while (x<m && y<n && a[x]==b[y]) {
    x++;
    y++;
  }
  fp[k] = y;
  pt = path.length
  path[pt] = pre + "," + x + "," + y;
  lst[k] = pt;
}

function paramsFromQueryString(s) {
    var pairs = s.split('&');
    var params = {};
    pairs.map( function (p)  { 
        var [k,v]  = p.split("=")
        k = k.replace( /^\?/, '' );
        params[k] = v;
    } );
    return params;    
}

function nop(n) { return n} 
function parsePathAndParams(u) {
  var m = u.match( /https?:\/\/([^/]+)(:\d+)?(\/[^?#]*)(?:\?(.+))?/ );
  var params = {};
    if ( m[4] ) {
        params = paramsFromQueryString(m[4]);
    }
    if ( m[3] ) {
      m[3].split(/\//).filter(nop).map( function (i, index) {
            params["path" + index] = i;
      } );
    }
  return params;  
}

function calcParamDiff(a, b) {
    var cost = 0;
    for ( var name in b ) {
        var v = b[name];
        var n;
        if ( v.match( /^\d+$/ ) ) {
            var u = a[name] || 1;
            n = Math.abs(v - u);
        } else {
            var u = a[name] || "";
            n = diff_onp(u, v, "+", "-").filter ( function (i) {
                return i.command != "common"
            } ).length;
        }
        cost += n;//Math.pow(n, 1);
    }
    return cost;
}

var me  = parsePathAndParams("http://mozillazine.jp/");

//var candidate = parsePathAndParams("http://mozillazine.jp/?paged=2")

$x('//a[contains(text(), "前")]').map ( function (e) {
    return parsePathAndParams(e.href);
} ).map( function (p) {
 return calcParamDiff(me, p);
} );