【问题标题】:Javascript iteration count array instances in another arrayJavascript迭代计数另一个数组中的数组实例
【发布时间】:2019-06-07 14:12:49
【问题描述】:

我觉得这里有很多类似的问题,但由于我仍然被困住,我想我会问。这是一个 codecademy 的 linter 问题,我无法收集一个数组元素在另一个数组中的实例数。

即使使用其他人在 Git 中提供的解决方案,我也无法做出“我自己”的答案。我在 S.O. 中看到了很多类似的解决方案。但仍然没有继续前进。

数组 1

[ a, b, c, d, e, a, b, c, d, e, a,...]

数组 2

[a, b]

代码

const newConstant = (array1.forEach(foo) => {
     array2.filter (bar) => {
         if (foo[i] === bar[i]) {
             newConstant++;
         }
     }
});

我可能是在贬低我所看到的解决方案,并采取了两全其美的做法。但是,当我在 3 次会议中看了将近 2 个小时时,我只是有点眼花缭乱。为什么我不能收集 a 和 b 在数组 1 中出现的次数?

错误:

SyntaxError: Unexpected token'

【问题讨论】:

  • 善意的建议:把那段脚本扔进垃圾箱,检查箭头函数的工作原理,.forEach().filter() 做什么和返回,const 关键字做什么以及如何索引工作。
  • 根据w3schools.com/jsref/jsref_filter.asp 和foreach 一样,它们都期望函数,而不是foo 和bar 之类的名称;你从哪里得到 i 索引??
  • 伙计,没有冒犯的意思,但您必须首先了解您不能以任何顺序键入所有内容和任何内容。你有一个要尊重的语法。这就是为什么你会得到SyntaxError。检查每个([{ 是否有自己的)]}。请提供可读和可运行的代码。
  • 我刚刚学习了那些迭代 .forEach 和 .filter。我现在正在尝试使用它们。所以告诉我放弃一切去学习一些东西是没有帮助的。此外,这段代码尽可能地具有可读性。

标签: javascript arrays function syntax iterator


【解决方案1】:

你的代码有几个问题...

我认为您应该阅读变量声明和箭头函数,因为正如错误所述,您的语法不正确。

这是你的作品修改为具有所需的功能:

let newConstant = 0;
array1.forEach((foo) => {
    array2.filter((bar) => {
        if (foo === bar) {
            newConstant++;
        }
    })
});
console.log(newConstant);

但是,我会以不同的方式处理它,例如:

let count=0;
array1.map((elm1) => {
    if(array2.indexOf(elm1)!==-1) {
        count+=1;
    }
});
console.log(count);

【讨论】:

  • 谢谢!我犯了 3 个错误: 1. 当我需要递增它时,我错误地将我的新变量声明为常量。 2. 我错过了在数组过滤器中嵌入 foo 和 bar 参数的一组软括号。 3. 我在 foo 和 bar 中不必要地添加了方括号。我今天已经用完了我的投票,明天我会得到你。 :-)
【解决方案2】:

你有严重的语法错误,这里是语法的更正:

let newConstant = 0;
array1.forEach( foo => {
    array2.filter( bar => {
        if( foo === bar ){
            newConstant++;
        }
    } )

} );

你不能const 因为你正在增加变量的值(重新分配值),而这个关键字const 意味着你想给它一个初始值并且永远不要改变它。 所以用let替换它,它允许改变变量的值。

forEachfilter 两种方法将函数作为参数,在此代码中,您使用的是箭头函数 foo => { ... },但语法错误。

因此,您需要将此函数作为forEachfilter 的参数传递,方法是将整数放在forEach( HERE! ) 的括号之间... 例如:array1.forEach( foo => { ... } )

我看到你的最后一件事是你在声明和分配给那个变量时试图增加newConstant,这是不可能的,或者至少它不起作用。

【讨论】:

  • 不要犯和OP一样的错误。不要滥用Array#filterArray#forEach
  • doh,const 的建议似乎是真的,我注定要在这里失败,因为我永远不会让这一切发生在我自己...
  • @Thomas 我离开了Array#filter,因为它不会混淆发布问题的“Darryl Calder”,因为我已经更改了他的代码并解释了为什么以及我做了什么,只是更正了语法。
【解决方案3】:

既然你已经得到了一些答案,我想我会提供一个替代方案。这可能比其他一些答案慢一点,但我喜欢它的阅读方式。

var findNeedles = function (needle, haystack) {
  return haystack
    // we only need to check as far as there is room for the needle
    .slice(0, haystack.length - needle.length + 1)
    // get each subsection that may match the needle (same length)
    .map((c, i, a) => haystack.slice(i, i + needle.length))
    // filter out sections that match the needle
    .filter(c => c.every((e, i)=> e === needle[i] ));
}

var haystack = [ "a", "b", "c", "d", "e", "a", "b", "c", "d", "e", "a"];
var needle = ["a", "b"];
console.log("Found matches: ", findNeedles(needle, haystack).length);

如果您不确定,您还可以将内容进一步分解以使其更具可读性。例如

var findNeedles = function (needle, haystack) {
  var getPotentialNeedle = (c, i, a) => haystack.slice(i, i + needle.length);
  
  var needlePartMatches = (part, index) => part === needle[index];
  
  var isNeedle = (potentialNeedle) => potentialNeedle.every(needlePartMatches);
  
  return haystack
    // we only need to check as far as there is room for the needle
    .slice(0, haystack.length - needle.length + 1)
    .map(getPotentialNeedle)
    .filter(isNeedle);
}

var haystack = [ "a", "b", "c", "d", "e", "a", "b", "c", "d", "e", "a"];
var needle = ["a", "b"];
console.log("Found matches: ", findNeedles(needle, haystack).length);

【讨论】:

  • 谢谢,slice 和 map 也是我这几天刚刚接触到的迭代。一般来说,我仍在为 javascript 的语法和操作顺序而苦苦挣扎。
  • 作为一个简单的解释 slice 只是返回一个从索引 x 到 y 的子数组。 map 接受 lambda/arrow function,循环遍历每个项目,并传递项目 (c)、索引 (i) 和数组 (a),然后根据返回值构建一个新数组。 Lambda 函数非常简单。它们只是参数、=> 和返回值。在我的示例中,我从 index 开始返回另一个切片,并为第一张地图返回 index + needle 长度,并对过滤器进行布尔检查。
  • 谢谢,这些迭代是他们自己的,在课程中它们看起来并不复杂,但是当有多个时 )]};我对一项功能的要求感到困惑。 :-/ 很快,我需要退后一步,改进我的词汇表。
  • 只是一些友好的建议,继续学习,因为你需要了解如何读/写语法,但尽量避免这样的代码。您可以随时调整代码并拆分部分以使其更具可读性。我添加了另一个例子。它做同样的事情,但使用较少的嵌套。我创建了三个具有漂亮易读名称的变量函数,并且您不再有任何链式大括号。如果它可以帮助您更好地阅读它,请不要害怕编写更长的代码,很多人认为短===好!
【解决方案4】:

简单的解决方案,

var array1  = [ 'a', 'b', 'c', 'd', 'e', 'a', 'b', 'c', 'd', 'e', 'a'];

var array2 =  ['a', 'b', 'a'];

var result = {};

array2.forEach((elem) => {
    let count = array1.filter(element => element === elem);
    result[Symbol('a')] = count.length; // Here we use symbols to catch hold of repeated elements
});

console.log(result);

【讨论】:

    【解决方案5】:

    简单的解决方案;)

    let arr1 =  [ 'a', 'b', 'c', 'd', 'a', 'b', 'b'];
    let arr2 = ['a', 'b'];
    let obj= {};
    arr1.forEach(x => {
            arr2.forEach(y => {
                if(y === x){
                    if(obj[x]){
                    obj[x] = obj[x] + 1;
                } else {
                    obj[x] = 1;
                }
            }
        });
    });
    
    console.log(obj);
    

    【讨论】:

    • TO 显然是个初学者。从长远来看,向他扔一堆代码不会有帮助。添加一些解释为什么他的解决方案不起作用以及您所做的更改以及原因。
    猜你喜欢
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    • 2011-07-07
    • 2019-07-15
    • 1970-01-01
    • 2018-08-18
    • 1970-01-01
    • 2021-04-27
    相关资源
    最近更新 更多