【问题标题】:Manipulate more javascript array based on another array基于另一个数组操作更多 javascript 数组
【发布时间】:2017-01-05 19:19:52
【问题描述】:

我有一件奇怪的事情要做,但我不知道如何开始

我从这个变量开始

var base = [1,1,1,2,3,5,7,9,14,19,28,40,56,114,232,330];
var sky = [0,0,0,3,4,5,6,7,8,9,10,11,12,14,16,17];
var ite = [64,52,23,38,13,15,6,4,6,3,2,1,2,1,1,1];

所以要开始所有3个数组的长度相同,第一个操作是查看天空数组中是否有重复值,在这种情况下,0是重复的,只有在这种情况下才在末尾,但是天空阵列一直被排序。因此,我必须从天空中删除所有重复项(在本例中为 0),并从基础中删除相应的项目,并对 ite 上的相应项目求和。所以如果位置 4,5 有重复,我必须操纵这个条件。但是让我们看看新的 3 数组:

var new_base = [1,2,3,5,7,9,14,19,28,40,56,114,232,330];
var new_sky = [0,3,4,5,6,7,8,9,10,11,12,14,16,17];
var new_ite = [139,38,13,15,6,4,6,3,2,1,2,1,1,1];

如果你看到 new_ite 有 139 而不是 64,52,23,即 64+52+23 的总和,因为天空上的前 3 个项目是相同的 (0),所以我从 base 中删除了两个相应的值还有天空,我将相应的值加到 new_ite 数组中。

有快速的方法吗?我想到了一个 for 循环,但我坚持在第一个 for (i = 0; i

J

【问题讨论】:

  • 时间在这方面重要吗?它会被用在巨大的阵列上吗?是否存在内存限制(我们可以复制数组以快速排序吗?)?
  • 您必须使用这些提供的数组吗?或者你能改变这些数组的存储和表示方式吗?如果这些数组确实以您所描述的方式彼此相关,那么拥有一个对象数组可能更有意义,并且每个对象都有一个基础值、天空值和 ite 值。
  • 数组总是预排序的吗?
  • @Grallen arr sky 和 ​​base 总是排序的,性能对我来说很重要,但不是很大的数组,最多可能 100 或 200 个项目。对于我可以复制的 tj-rockefeller,这些数组彼此相关,但填充了 3 个不同的操作和部分代码。

标签: javascript arrays


【解决方案1】:

在循环期间从数组中删除元素时,诀窍是从末尾开始并移到前面。它使许多事情变得更容易。

for( var i = sky.length-1; i>=0; i--) {
    if (sky[i] == prev) {
        // Remove previous index from base, sky
        // See http://stackoverflow.com/questions/5767325/how-to-remove-a-particular-element-from-an-array-in-javascript
        base.splice(i+1, 1);
        sky.splice(i+1, 1);

        // Do sum, then remove
        ite[i] += ite[i+1];
        ite.splice(i+1, 1);
    }
    prev = sky[i];
}

我不会谈论这是否是“最快的”,但它确实有效,而且它在需要很少的程序员时间来编写和理解方面是“快的”。 (这通常是最重要的一种快速。)

【讨论】:

  • Tnx,目前这似乎是最快的解决方案
【解决方案2】:

我会建议这种解决方案,其中 j 用作新数组的索引,而 i 用作原始数组:

var base = [1,1,1,2,3,5,7,9,14,19,28,40,56,114,232,330];
var sky = [0,0,0,3,4,5,6,7,8,9,10,11,12,14,16,17];
var ite = [64,52,23,38,13,15,6,4,6,3,2,1,2,1,1,1];

var new_base = [], new_sky = [], new_ite = [];

var j = -1;
sky.forEach(function (sk, i) {
    if (!i || sk !== sky[i-1]) {
        new_ite[++j] = 0;
        new_base[j] = base[i];
        new_sky[j] = sk;
    }
    new_ite[j] += ite[i];
});

console.log('new_base = ' + new_base);
console.log('new_sky = ' + new_sky);
console.log('new_ite = ' + new_ite);

【讨论】:

  • Tnx 经编是一个开始 :D
  • 不确定我理解您所说的“开始”是什么意思。有什么我错过的吗?
  • 抱歉没有提到你的工作,对我来说是一个开始 :D 这对我来说只是一个起点,现在我必须用这些数据做其他事情,而且更“复杂”我'我会开一个新帖子,tnx。
  • 啊,我明白了。不要忘记mark one of the answers as accepted
【解决方案3】:

您可以使用Array#reduce根据规则从原始数组创建新数组:

var base = [1,1,1,2,3,5,7,9,14,19,28,40,56,114,232,330];
var sky = [0,0,0,3,4,5,6,7,8,9,10,11,12,14,16,17];
var ite = [64,52,23,38,13,15,6,4,6,3,2,1,2,1,1,1];

var result = sky.reduce(function(r, n, i) {
  var last = r.sky.length - 1;
  
  if(n === r.sky[last]) {
    r.ite[last] += ite[i];
  } else {
    r.base.push(base[i]);
    r.sky.push(n);
    r.ite.push(ite[i]);
  }
  
  return r;
}, { base: [], sky: [], ite: [] });

console.log('new base:', result.base.join(','));
console.log('new sky:', result.sky.join(','));
console.log('new ite:', result.ite.join(','));

【讨论】:

    【解决方案4】:

    atltag 的回答是最快的。请看:

    https://repl.it/FBpo/5

    【讨论】:

    • Tnx 为这个,但为什么要从新数组开始呢?
    • 我认为新数组是用于保护原始数据的副本。我在这里所做的对数组具有破坏性;
    • 你说速度很重要(就像你可能每秒运行这么多次)。我认为构建新数组比拆分多次更快。我要测试然后更新我的答案。
    • 第二次没有多少时间,但我有一点时间可以做所有事情!顺便说一句,您的脚本从解决方案数组开始,而不是从开始的数组开始
    • 发布了新的快速答案。
    【解决方案5】:

    只需在 O(n) 时间内使用一个 .reduce(),您就可以执行以下操作; (我在赋值部分使用了数组解构。可能会选择使用三个.push()s)

    var base = [1,1,1,2,3,5,7,9,14,19,28,40,56,114,232,330],
         sky = [0,0,0,3,4,5,6,7,8,9,10,11,12,14,16,17],
         ite = [64,52,23,38,13,15,6,4,6,3,2,1,2,1,1,1],
     results = sky.reduce((r,c,i) => c === r[1][r[1].length-1] ? (r[2][r[2].length-1] += ite[i],r)
                                                               : ([r[0][r[0].length],r[1][r[1].length],r[2][r[2].length]] = [base[i],c,ite[i]],r),[[],[],[]]);
    console.log(JSON.stringify(results));

    【讨论】:

    • Tnx,我一直很喜欢你的解决方案:D
    • 到目前为止所有的解决方案都是 O(n)。
    • @alttag 老实说,我没有检查其他答案.. 但是查看你的答案......所以你相信三个级联的.splice(x,1)s,但只有一个,是 O(1) 操作..?
    • 你找到我了;我忽略了splice() 的成本。不过,这在很大程度上取决于特定 Javascript 引擎的内部结构。 This answer 建议 splice() 是 O(n),但对它的评论建议 O(1)。删除肯定是 O(1),O(n) 复杂性会出现在索引重新分配中,尽管在实践中使用非常低的常量修饰符。如果目标是低 O(),则可以将值设置为 null 而不是删除/重新分配,然后重新创建,因此 O(2n) = O(n),但这听起来更慢。顺便说一句,我喜欢你回答的优雅。
    猜你喜欢
    • 1970-01-01
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 2015-08-22
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多