【问题标题】:Count occurrences in array given values of another array给定另一个数组的值,计算数组中出现的次数
【发布时间】:2014-09-29 14:58:09
【问题描述】:

我正在为 Google 电子表格编写脚本。

数组1有一系列的名字(50多个不同的名字)

John, Pete, Paul, ... Michael

数组 2 是从给定的 50 个名称(总共超过 10K)中的一系列重复名称

Paul, Michael, Pete, John, Paul, Paul, Pete, Michael, Paul, Michael,... Michael

如何创建另一个数组,其中包含数组 1 中每个给定名称的出现次数(数组 2)?

无法排序。因此,数组 3 应该考虑数组 1 的顺序。在这种情况下,例如:

1, 2, 3,... 4

如果顺序不重要,我已经看到并证明了如何做到这一点(从数组 2 开始,数组 1 是使用唯一名称创建的,数组 3 包含它们的出现 --> Counting the occurrences of JavaScript array elements),但我所有的方法似乎都没有不行。到目前为止,我有这个:

var namesCountArray = [];
namesArray = ss.getRange("CU3:CU" + rows + "").getValues();
namesSerieArray = ss.getRange("DF3:DF" + rows + "").getValues();

for(var i=0; i< namesArray.length; i++) {
    var count = 0;
    for(var i = 0; i < namesSerieArray.length; ++i) {
        if(namesSerieArray[i] == namesArray[i])
            count++;
    }
    namesCountArray.push([count]);
}
ss.getRange("DB3").setValue(namesCountArray);

【问题讨论】:

  • 您真的需要使用脚本来执行此操作吗?您可以简单地使用 counta 公式或更复杂的分析数据透视表?

标签: javascript arrays google-sheets


【解决方案1】:

您需要在第二个 for 循环中使用不同的变量或将其全部取出:

for(var i=0; i< namesArray.length; i++) {
  var count = 0;
  for(var i = 0; i < namesSerieArray.length; ++i){
  if(namesSerieArray[i] == namesArray[i])
    count++;
  }

您正在检查每一对 1 和 1、2 和 2、3 和 3。如果要检查每个索引对(1 与 1、1 与 2 ...),则应使用单独的变量。例如:

for(var i=0; i< namesArray.length; i++) {
  var count = 0;
  for(var j = 0; j < namesSerieArray.length; j++){
  if(namesSerieArray[i] == namesArray[j])
    count++;
  }

【讨论】:

  • 好眼光。我完全错过了i 用于两个循环。 count 被推送为 [count],因此如果不需要该包装数组,这也可能是一个问题。
  • 对,他可能打算这样。没有把握。然而,循环实际上是封闭的。 if 语句不使用花括号。 :)
  • 是的,我后来注意到了这一点并删除了我的评论,因为我是个傻瓜。但是,是的,我不知道他到底想要什么,所以我就不管了。 xP
  • @CharlesB.,谢谢。你一点也不傻(我红了原来的味精,但直到现在还不能回答)。我不得不承认我的无知。今天是我使用数组的第一天,一个月前我还没有任何经验,所以可能原始代码完全错误。 @squint,我正在使用 [count],因为 Google App Scripts 需要它。至少与其他数组一起工作,因为没有[] 它总是说无法将数组转换为对象。但是,由于我的代码最初是错误的,它可能不需要括号。
  • 但是,问题是我无法让它工作。你认为这是因为 Google App Scripts 在调用namesArray = ss.getRange("CU3:CU" + rows + "").getValues(); 时会生成二维数组吗?如果我在一个单元格中打印这个数组,我会得到类似[[Pete], [John], [Paul],... [Michael]] 而不是["Pete", "John", "Paul",... "Michael"]
【解决方案2】:
// names we want to find
var names = ["john", "pete", "paul"];

// target list of names.
// john, pete, paul appear 2x
var target = ["john", "pete", "jack", "cindy", "thomas", "paul", "john", "pete", "paul"];

function finder(search, target) {
    return search.map(function (val) {
        return target.filter(function (e) {
            return val === e;
        }).length;
    });
}

finder(names, target);
// => [2, 2, 2]

演示: http://jsfiddle.net/austinpray/v14o38ta/

【讨论】:

  • 杰克和辛迪是船员的第 13 和第 14 名成员;)
  • @RyanWheale 哈哈我不明白,你是什么意思?
  • 其中大部分是门徒的名字......其中有 12 个。虽然迈克尔和保罗不是门徒,但我只是觉得你没有坚持圣经范式很有趣。跨度>
  • thx @AustinPray 它在小提琴上工作得很好,但(通常)在我的实现中没有。你认为这是因为我在第一个答案中的评论吗?
  • @agustin 我将编辑我的答案以使其正常工作。你能给我一个示例“目标”数组吗?
【解决方案3】:

遍历数组 2 并构建一个对象,其中每个键作为名称,值作为其出现次数。

例如

var array2 = ["Paul", "Michael", "Pete", ... /* 47 more names */ ];
var occurences = {};

for (var i = 0, l = array2.length; i++; i<l) {
   if (occurences[array2[i]] === undefined) {
     occurences[array2[i]] = 1;
   }
   else {
     occurences[array2[i]]++;
   }
}

然后遍历第一个数组,检查名称是否在对象occurences 中并将其值推送到新数组中,像这样

var array1 = ["Paul", "Michael", "Pete", "John", "Steve", "Bill" ];
var array1Frequency = [];

for (var i = 0, l = array1.length; i++; i<l) {
    array1Frequency.push(occurences[array1[i]] || 0)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-05
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多