【问题标题】:Does JavaScript support array/list comprehensions like Python?JavaScript 是否支持像 Python 一样的数组/列表解析?
【发布时间】:2015-09-29 22:29:54
【问题描述】:

我正在练习/学习 JavaScript 和 Python。我想知道 Javascript 是否与这种类型的编码等效。

出于练习目的,我基本上是尝试从字符串中的每个整数中获取一个数组。我比 JavaScript 更精通 Python

Python:

string = '1234-5'

forbidden = '-'

print([int(i) for i in str(string) if i not in forbidden])

上面的 Javascript 是否有类似的事情需要我做?

【问题讨论】:

  • 不,它没有。尽管 JavaScript 确实支持 higher-ordered functions 并且 ES5 在 Array.prototype 中添加了对一些基本地图/过滤器的支持(没有直接的平面地图,尽管可以模拟 map-concat)。还有一些额外的库,比如下划线,它们添加到这组“原语”中,这就是 Python 在列表理解语法伪装下所做的一切。

标签: javascript python


【解决方案1】:

更新: 数组推导已从标准中删除。引用MDN:

数组解析语法是非标准的,并从 Firefox 58 开始删除。对于面向未来的用法,请考虑使用 Array.prototype.map、Array.prototype.filter、箭头函数和传播语法。

查看this answer 以获取Array.prototype.map 的示例:

let emails = people.map(({ email }) => email);

原答案:

是的,JavaScript 将在即将推出的 EcmaScript 版本 7 中支持 array comprehensions

这是example

var str =  "1234-5";
var ignore = "-";

console.log([for (i of str) if (!ignore.includes(i)) i]);

【讨论】:

  • 我相信 OP 是在询问他们今天可以实际运行的 JavaScript 代码,而不是在未来某个不确定的时间。
  • 巴别塔太棒了!也许您可以稍微扩展您的答案,并举例说明语法是什么,以及如何使用 Babel 在当今的浏览器中使用它。
  • 当然,请参阅更新。 @user2864740:它就是这样,但是数组解析将成为 ES7 的一部分,并且现在可以使用 Babel。
  • MDN 页面developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 在顶部说:“数组推导是非标准的,不太可能添加到 ECMAScript 中”。 stackoverflow.com/questions/33872615/… 好像有更多细节
  • 万一其他人在多年后偶然发现这个答案,这并不像上面链接中提供的“示例”所证明的那样有效。
【解决方案2】:

鉴于问题的 Python 代码

print([int(i) for i in str(string) if i not in forbidden])

这是对 JavaScript (ES2015) 的最直接翻译:

const string = '1234-5';
const forbidden = '-';

console.log([...string].filter(c => !forbidden.includes(c)).map(c => parseInt(c)));
// result: [ 1, 2, 3, 4, 5 ]

以下是使用的 Python 和 JavaScript 代码元素的比较: (Python -> Javascript):

  • 打印-> console.log
  • 遍历字符串中的字符 -> spread operator
  • 列表理解 'if' -> Array.filter
  • 列表理解 'for' -> Array.map
  • 字符串中的子字符串? -> string.includes

【讨论】:

    【解决方案3】:

    阅读代码,我假设禁止可以有超过 1 个字符。我还假设输出应该是“12345”

    var string = "12=34-5";
    
    var forbidden = "=-";
    
    console.log(string.split("").filter(function(str){
        return forbidden.indexOf(str) < 0;
    }).join(""))
    

    如果在不同的行上输出“1”“2”“3”“4”“5”

    var string = "12=34-5";
    
    var forbidden = "=-";
    
    string.split("").forEach(function(str){
        if (forbidden.indexOf(str) < 0) {
            console.log(str);
        }
    });
    

    【讨论】:

      【解决方案4】:

      不是直接的,但不难复制。

      var string = "1234-5";
      
      var forbidden = "-";
      
      string.split("").filter(function(str){
          if(forbidden.indexOf(str) < 0) {
              return str;
          }
      }).forEach(function(letter) { console.log(letter);});
      

      我猜的更直接:

      for(var i=0 ; i < str.length ; i++) {
          if(forbidden.indexOf(str) < 0) {
              console.log(str[i]);
          }
      }
      

      但是在你的 for 循环中没有内置的过滤方式。

      【讨论】:

        【解决方案5】:

        您可以使用应用程序函子轻松实现此行为。

        Array.prototype.ap = function(xs) {
          return this.reduce((acc, f) => acc.concat(xs.map(f)), []) 
        }
        
        
        const result = [x => x +1].ap([2])
        console.log(result)
        

        【讨论】:

        • 你的意思是应用函子吗?您能否为您的答案提供更多背景信息?这很有趣。
        • 虽然乍一看似乎很有趣,但我看不出有任何理由使用它来代替普通的[2].map( x =&gt; x+1)
        • 我的猜测是它模仿了 python 等价物的感觉
        【解决方案6】:

        JavaScript 不再支持数组解析。

        我也在寻找等效的 JavaScript。 Mozilla 开发者的Network indicates that this functionality is no longer supported. 上述链接中引用了首选语法。

        【讨论】:

          【解决方案7】:

          为了“完整性”,这里有一个较短的正则表达式版本。

          var str =  "1234-5";
          var ignore = "-=";
          
          console.log(str.replace(new RegExp(ignore.split("").join("|")), "").split(""));
          

          编辑:为了确保 RegExp 不会“阻塞”特殊字符,ignore 可以实现为 regexp 文字,而不是字符串:

          var str =  "1234-5";
          var ignore = /[\+=-]/;
          console.log(str.replace(ignore, "").split(""));
          

          【讨论】:

          • var ignore = "-+=";
          • 当,我也很喜欢你的解决方案;它更多地属于我的编码类型
          【解决方案8】:

          它确实有一个糟糕的男人版本

          const string = '1234-5'
          
          const forbidden = '-'
          
          print([int(i) for i in str(string) if i not in forbidden])
          const result = string.split('').filter(char => char !== forbidden);
          console.log(result)
          

          在 JS 中,您只能迭代数组中的单个元素,因此无法像 Python 中那样一次提取多个条目。

          对于这种特殊情况,您应该使用正则表达式来过滤字符串。

          【讨论】:

          • 请将javascript和python代码放在​​两个单独的代码块中。
          【解决方案9】:

          你可以看看 CoffeeScript。 CoffeeScript 为 java-script 添加了缺失的功能,并允许您编写更清晰、更易读的代码。 https://coffeescript.org/#coffeescript-2

          您编写一个 .coffee 文件,然后 coffeScript-compiler 将您的咖啡文件编译为 JavaScript 文件。因为转换成 JavaScript 是通过编译完成的,所以脚本的运行速度不会变慢。

          所以您的代码在咖啡脚本中将如下所示:

          string = '1234-5'
          
          forbidden = '-'
          
          alert(JSON.stringify(+i for i in string when i isnt forbidden))
          

          老实说,这比 python 对应物更容易阅读。它可以快速编译成闲置的 JavaScript:

          var forbidden, i, string;
          
          string = '1234-5';
          
          forbidden = '-';
          
          alert(JSON.stringify((function() {
            var j, len, results;
            results = [];
            for (j = 0, len = string.length; j < len; j++) {
              i = string[j];
              if (i !== forbidden) {
                results.push(+i);
              }
            }
            return results;
          })()));
          

          您甚至不需要安装任何东西。您可以在他们的网站上使用它,它会显示翻译后的 JavaScript 代码。

          【讨论】:

            猜你喜欢
            • 2017-04-20
            • 1970-01-01
            • 1970-01-01
            • 2011-11-20
            • 1970-01-01
            • 2014-11-26
            • 2019-03-07
            • 1970-01-01
            • 2011-10-16
            相关资源
            最近更新 更多