【问题标题】:sorting two associative arrays/stacks对两个关联数组/堆栈进行排序
【发布时间】:2018-02-22 16:24:41
【问题描述】:

我正在实现我设计的算法并正在探索不同的方法

这不是一个家庭作业问题,但我会像这样解释它:假设一个商人在不同的日子购买了苹果库存,并在不同的日子卖了一些。我想要他们当前购买的加权平均时间戳。

我将此数据对象存储为纪元时间的时间戳字符串和苹果的数量。我的数据集实际上在单独的数据集中包含购买和销售,如下所示:

//buys
var incomingArray = {
  "1518744389": 10,
  "1318744389": 30
};

//sells
var outgoingArray = {
  "1518744480": 3,
  "1418744389": 5,
  "1408744389": 8
};

我希望结果只显示剩余的incomingArray 时间戳购买对。

var incomingArrayRemaining = {
  "1518744389": 7,
  "1318744389": 17
};

您会看到在较晚的时间戳有 3 个苹果的一笔传出交易,因此从 10 中减去。在购买 10 之前有 13 笔传出交易,但在购买 30 之后,因此它们仅从 30 中减去.

注意,如果在10之后转移超过10个,则从10和30中减去。苹果的数量永远不能小于0。

首先,为了实现我的目标,我似乎需要知道他们购买的地段实际上仍然拥有多少。

与其在 LIFO 方法中进行堆栈减法,不如说这更像是税务批次会计。批次本身必须独立处理。

因此,我必须在传出数组中获取卖出的第一个索引的时间戳,并在传入数组中找到最近的买入时间戳

这是我尝试过的:

for (var ink in incomingArray) {
  var inInt = parseInt(ink);

  for (var outk in outgoingArray) {
    if (inInt >= 0) {
      var outInt = parseInt(outk);

      if (outInt >= inInt) {
        inInt = inInt - outInt;
        if (intInt < 0) {
          outInt = inInt * -1; //remainder
          inInt = 0;
        } //end if
      } //end if
    } //end if
  } //end innter for
} //end outer for

它是不完整的,嵌套的 for 循环解决方案的计算时间已经很差了。

该函数只是尝试对交易进行排序,以便只剩下剩余余额,方法是从最近的传入余额中减去传出余额,并将剩余部分带到下一个传入余额中

我觉得递归解决方案会更好,或者可能是我没想到的更优雅的解决方案(javascript 中的嵌套 Object forEach 访问器)

在对它们进行排序之后,我需要实际执行加权平均方法,我已经有了一些想法。

先排序,然后对剩余数量进行加权平均。

无论如何,我知道 StackOverflow 上的 javascript 社区对寻求帮助特别苛刻,但我陷入了僵局,因为我不仅想要一个解决方案,还想要一个计算效率高的解决方案,所以我可能会在它上面投入大量资金.

【问题讨论】:

  • 我实际上读了三遍,仍然没有得到你想要的东西。你能提供一个示例输出吗?
  • 需要注意的一点,您要求的是高效而优雅的解决方案,而这两个属性通常是相反的:)
  • @JonasW。我添加了示例输出
  • “在某个时间戳内”您的 epsilon 是多少?你什么时候停下来?

标签: javascript json sorting nested-loops


【解决方案1】:

您可以将对象转换为时间戳-值对数组。传出的可能是负面的。然后你可以很容易地在时间戳之后对它们进行排序并积累你喜欢的方式:

 const purchases = Object.entries(incomingArray).concat(Object.entries(outgoingArray).map(([ts, val]) => ([ts, -val])));

 purchases.sort(([ts1, ts2]) => ts1 - ts2);

现在您可以迭代时间跨度,并在值增加时将增量存储在一个新数组中(新输入):

 const result = [];
 let delta = 0, lastIngoing = purchases[0][0];

 for(const [time, value] of purchases){
   if(value > 0){
    // Store the old
    result.push([lastIngoing, delta]);
    // Set up new
   delta = 0;
   lastIngoing = time;
  } else {
   delta += value;
  }
}

【讨论】:

  • 啊,好样的!我注意到这会创建一个数组数组[ [ '1518744480', -410 ], [ '1518744479', 400 ]... 而不是对象,这改变了我可以操作它的方式。例如,我必须使用嵌套的 for 循环来访问任何元素,而不是使用 forEach 方法。对此有什么想法?
  • @cqm 不认为它是一个元组数组。您可以像 for(const [timestamp, value] of purchases) 一样对其进行迭代
  • 嗯,我明白了,这真的是一个单独的问题,我不熟悉那种语法,我将如何访问那个 for 循环中的常量,最终我将如何进行加法和同时删除索引以获得剩余的values > 0?
  • @cqm 已编辑以显示可能的用法。我仍然不确定这是否是您正在寻找的东西,但我认为它朝着正确的方向发展。
  • 关闭,我要问一个不同的问题并链接你。排序部分是一流的!
猜你喜欢
  • 2013-05-13
  • 2015-01-14
  • 1970-01-01
  • 2011-06-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-19
相关资源
最近更新 更多