将0放在javascript中两个数组的相同位置

时间:2016-01-26 15:25:53

标签: javascript arrays charts

对不起我的英语,真的很累......

想象一下两个数组:

var a = [-10, 5, 0, 5, 10, 15];
var b = [-20, 0, 20, 40, 60, 80];

每个数组的每个值增加相同的数字(a减5,b增加20。 我想找到一种方法将零置于两个阵列上的相同位置。

请记住:

  • 每个系列具有相同数量的元素
  • 您可以更改每个阵列的最小值和最大值(系列的原始最小值和最大值必须是系列的一部分,请查看下面的示例)
  • 数组的每个值递增相同的数字,您可以更改此值

预期结果可能类似于

var a = [-10, 5, **0**, 5, 10, 15];
var b = [-60, -30, **0**, 30, 60, 90];

b现在增加30,原始的min(-20)和max(8)值包含在间隔中。

有关如何使用javascript进行此操作的想法吗?

我为什么要这样做?要解决这样的问题: http://peltiertech.com/Excel/Charts/AlignXon2Ys.html

提前致谢

罗布

4 个答案:

答案 0 :(得分:1)

以下是基于注释的代码迭代结果。为清晰起见,以前的代码已被删除,但在编辑历史记录中仍然可用。

这个修正了系列中间的零点,然后根据初始要求调整值。也是四舍五入到最接近的5(前面的代码在这方面是不充分的,对不起)。 HTH。

function develop(data) {
  if (data.length < 3) {
    return data;
  }

  var lower = data[0];
  var upper = data[data.length - 1];
  var index = (data.length - 1) / 2;
  var numLeft = Math.floor(index);
  var numRight = Math.ceil(index);
  var leftStep = findStep(lower, numLeft, false);
  var rightStep = findStep(upper, numRight, true);
  var step = roundStep(Math.max(leftStep, rightStep), 5);
  var result = [];
  for (var ii = 0; ii < data.length; ii++) {
    result[ii] = step * (ii - numLeft);
  }
  return result;

  // ---

  function findStep(boundary, numEntries, positive) {
    if (positive && boundary <= 0 || !positive && boundary >= 0) {
      return 1;
    }
    return Math.abs(Math.ceil(boundary / numEntries));
  }

  function roundStep(step, roundTo) {
    if (step < roundTo) {
      return step;
    }
    return Math.ceil(step / roundTo) * roundTo;
  }

}

function test() {
  var testData = [
    [-10, -5, 0, 5, 10, 15],
    [-20, 0, 20, 40, 60, 80],
    [0, 72, 144, 216, 288, 360],
    [-30, -25, -20, -15, -10, 0]
  ];
  var results = [];
  for (var ii = 0; ii < testData.length; ii++) {
    var data = testData[ii];
    results.push(JSON.stringify(data) + " => " + develop(data));
  }
  document.getElementById("results").innerHTML = results.join("<br>");
}
<input type="button" value="test()" onclick="test()" />
<div id="results"></div>

答案 1 :(得分:0)

这似乎有效,但我可能做了几件不必要的事情

var setIndex = function (arr1, arr2) {
  var arr1Min = arr1[0];
  var arr2Min = arr2[0];
  var arr1Max = arr1[arr1.length-1];
  var arr2Max = arr2[arr2.length-1];
  var length = arr1.length;
  var newRatio;
  var newMin;
  var newMax;

  var ratioArr1 = arr1Max/arr1Min;
  var ratioArr2 = arr2Max/arr2Min;

  if(ratioArr1 < ratioArr2){
    newMin = calcNewMin(arr1Min, arr1Max, ratioArr2);

    newMax = ratioArr2 * newMin;
    newRatio = (newMax - newMin)/(length-1);

    arr1 = [];
    for(var i = 0; i < length; i++){
      arr1.push(newMin + (i * newRatio));
    }
    return [arr1, arr2];

  } else {
    newMin = calcNewMin(arr2Min, arr2Max, ratioArr1);

    newMax = ratioArr1 * newMin;
    newRatio = (newMax - newMin)/(length-1);

    arr2 = [];
    for(var i = 0; i < length; i++){
      arr2.push(newMin + (i * newRatio));
    }
    return [arr1, arr2];
  }
};


var calcNewMin = function(min, max, ratio){
  var count = 1;
  var newMin = min;
  var newMax = max;
  while(newMax <= max){
    count++;
    newMin = min - count;
    newMax = newMin * ratio;
  }
  return newMin;
};

答案 2 :(得分:0)

首先比较数组范围,如果一个数组包含另一个数组的范围,那么答案是一个增量高于数组的系列,该数组在范围的开始处增加:

0 - increment * (position of 0)

在你的例子中:

var a = [-10, 5, 0, 5, 10, 15];
var b = [-20, 0, 20, 40, 60, 80];

b包含a的范围,因此任何增量高于b且遵守规则的系列都是该问题的有效解决方案:

[-20, 0, 20, 40, 60, 80]
[-21, 0, 21, 42, 63, 84]
[-22, 0, 22, 44, 66, 88]
...
[-60, 0, 60, 120, 180, 240]

所有这些系列都包含a

的范围

当范围重叠时,它会变得有点棘手:

[-10, 0, 10, 20, 30]
[ 0, 20, 40, 60, 80]

背后的想法是一样的。我们将选择具有最小值的系列:

[-10, 0, 10, 20, 30]

由此,我们需要找到更高的增量,以使其满足:

start + (inc * length) > max of other series.

开始时间:

0 - (inc * pos of 0 in picked series)

移动你身边的东西:

inc > (max value / (length - pos of 0 in picked series))

所以在这个例子中:

inc > 80 / (5 - 2)
inc > 80 / 3
inc > 26.666

让我们以27的增量和-27的开头尝试:

[-27, 0, 27, 54, 81]

现在,您知道如何解决问题,让我们尝试使用代码:

function getMinMax(a, b){
    var last = a.length - 1,
        min = a[0] < b[0] ? a : b,
        max = a[last] > b[last] ? a : b;

    return { min : min, max : max };
}

function closestInc(range){
    if(range.min === range.max){
        return range.min[1] - range.min[0];
    } else {
        var last = range.min.length - 1,
            maxValue = range.max[last],
            posOfCero = range.min.indexOf(0);
        return (maxValue/(range.min.length - posOfCero));
    }
}

因此,所有可能的答案都是增量值大于closestInc(a, b)且开头为-closestInc(a,b) * posOfCero的任何系列。

这是一个慢慢打印出所有可能值的函数:

function createSeries(inc, posOfCero, count) {
  var series = [],
    start = -(inc * posOfCero);

  for (var i = 0; i < count; i++) {
    series.push(start + (inc * i));
  }

  return series;
}

var a = [-10, 5, 0, 5, 10, 15],
  b = [-20, 0, 20, 40, 60, 80],
  ranges = getMinMax(a, b),
  inc = closestInc(ranges),
  posOfCero = ranges.min.indexOf(0);

setTimeout(function printSeries(i) {
  console.log(createSeries(inc + 1, posOfCero, range.min.length));
  setTimeout(printSeries, 1000, i + 1);
}, 1000, 1);

以下代码段:

&#13;
&#13;
function getMinMax(a, b) {
  var last = a.length - 1,
      min = a[0] < b[0] ? a : b,
      max = a[last] > b[last] ? a : b;

  return {
    min: min,
    max: max
  };
}

function closestInc(range) {
  if (range.min === range.max) {
    return range.min[1] - range.min[0];
  } else {
    var last = range.min.length - 1,
        maxValue = range.max[last],
        posOfCero = range.min.indexOf(0) + 1;
    return (maxValue / (range.min.length - posOfCero));
  }
}

function createSeries(inc, posOfCero, count) {
  var series = [],
      start = -(inc * posOfCero);

  for (var i = 0; i < count; i++) {
    series.push(start + (inc * i));
  }

  return series;
}

//var a = [-10, 5, 0, 5, 10, 15],
//    b = [-20, 0, 20, 40, 60, 80],
var a = [-10, 0, 10, 20, 30],
    b = [ 0, 20, 40, 60, 80],
    ranges = getMinMax(a, b),
    inc = closestInc(ranges),
    posOfCero = ranges.min.indexOf(0);

setTimeout(function printSeries(i) {
  console.log(createSeries(Math.round(inc + i), posOfCero, ranges.min.length));
  setTimeout(printSeries, 1000, i + 1);
}, 1000, 1);
&#13;
&#13;
&#13;

最后一点,这并非所有可能的系列符合您的规则(系列之间可能仍有一些有效的增量)。

答案 3 :(得分:-2)

您可以像jsFiddle

一样使用Array.pushArray.unshift