【问题标题】:Javascript - Restructure an array of strings based on prefixJavascript - 根据前缀重组字符串数组
【发布时间】:2016-01-20 09:12:55
【问题描述】:

我有一个包含文件名列表的数组:

var files = ['home_01.ai','home_02.ai','home_03.ai','imprint_01.ai','imprint_02.ai']

我想要做的是将这个数组重新组织成一个多维数组,将具有相同前缀的每个文件组合在一起。在这种情况下:

var firstArray = ['home_01.ai','home_02.ai','home_03.ai'], /*home*/
    secondArray = ['imprint_01.ai','imprint_02.ai']; /*imprint*/

当我的文件数组中可以有可变数量的前缀并且可以是任意长度时,我怎么能做到这一点?

【问题讨论】:

    标签: javascript arrays string object


    【解决方案1】:

    您可以遍历数组并在“_”上拆分文件名以获得前缀,然后将这些文件名添加到正确的数组中,按前缀索引。

    var files = ['home_01.ai','home_02.ai','home_03.ai','imprint_01.ai','imprint_02.ai'];
    var result = {};
    for (var i = 0; i < files.length; i++)
    {
        if (files[i].indexOf('_') < 0)
        {
            console.log("No prefix detected in '" + files[i] + "'.");
            continue;
        }
        var prefix = files[i].split('_')[0];
        if (!result[prefix])
            result[prefix] = [];
        result[prefix].push(files[i]);
    }
    
    console.dir(result);
    

    【讨论】:

    • 感谢四位您的回复。这正是我想知道的。但是我没有得到 lopp 的最后一部分“ if (!result[prefix])...” ..你为什么不用括号 {} 打开 if() ? .. 对不起,我是 nooby..
    • 如果ifforwhile 等块内的代码只有一行,则可以跳过括号。请注意,您不能对函数、对象声明或 try-catch 语句执行此操作。
    【解决方案2】:

    您可以使用AlaSQL JavaScript 数据处理库来做到这一点。

    以下是您的问题的解决方案:

    var res = alasql('COLUMN OF SELECT ARRAY(_) FROM ? \
         GROUP BY _->split("_")->0',[files]);
    

    此语句返回按前缀分组的数组数组:

    [ [ 'home_01.ai', 'home_02.ai', 'home_03.ai' ],
      [ 'imprint_01.ai', 'imprint_02.ai' ] ]
    

    这里:

    • COLUMN OF - 仅返回查询的第一列
    • 选择...从? GROUP BY ... - 选择语句
    • ARRAY(_) - 在数组中分组记录
    • 来自? - 从参数[文件]查询
    • GROUP BY ->split("")->0 - 取一个值,用 '' 分割它,然后取数组的第一个元素(类似于 JS r.split( '')[0]

    免责声明:我是 AlaSQL 的作者。

    【讨论】:

    • AlaSQL 是很好的库,但他不必为这个问题使用完整的库。
    • 1 行源代码与超过 10 行源代码。这就是我们需要库的原因:)
    • 对。我会使用该库,但不会在带宽很重要的 Web 项目中使用。对于 Nodejs,是的。我已经为它克隆了:) @agershun
    【解决方案3】:

    更新

    我错过了你可能有其他前缀。已更新以使用任何前缀。

    function splitFilesIntoTypes(_files, cb) {
      var result = [];
      // loop through the array
      _files.map(function(a, b){
          if(!result[a.split('_')[0]])
            result[a.split('_')[0]] = [];
        
          result[a.split('_')[0]].push(a);
      });
      return result
    }
    
    var files = ['another_01.ai','home_01.ai','home_02.ai','home_03.ai','imprint_01.ai','imprint_02.ai'];
    console.log(splitFilesIntoTypes(files));
    

    已修复

    假设您只有两种类型的名称(home_... 和 imprint_...)。我做了这个函数把它分成两个数组。

    // function takes array and returns two array to callback function
    function splitFilesIntoTypes(_files, cb) {
      // if you have only two types of names
      var _home = [], _imprint = [];
    
      // loop through the array
      _files.map(function(a, b){
          
          if(a.split('_')[0] === 'home') _home.push(a);
          if(a.split('_')[0] === 'imprint') _imprint.push(a);
      });
      
      if(typeof cb === "function")
        cb(_home, _imprint);
      
    
    }
    
    var files = ['home_01.ai','home_02.ai','home_03.ai','imprint_01.ai','imprint_02.ai'];
    
    splitFilesIntoTypes(files, function(firstArray, secondArray) {
    
      console.log(firstArray);
      console.log(secondArray);
      
    });
    

    【讨论】:

    • 问题指定files数组中可以有任意数量的不同前缀。
    • 您的答案被硬编码为两个前缀。如果数据发生变化,代码必须更改。
    【解决方案4】:

    var files = ['home_01.ai', 'home_02.ai', 'home_03.ai', 'imprint_01.ai', 'imprint_02.ai'];
    var result = files.reduce(function(prev, curr) {
      var index = curr.indexOf('_01.');
      if (index !== -1) {
        prev.push(index);
      }
      return prev;
    }, []).map(function(index) {
      return files.splice(0, index - 1);
    });
    
    
    document.body.textContent = JSON.stringify(result);

    请注意,此答案假定 files 已按字母顺序排序。

    【讨论】:

      【解决方案5】:

      我使用与 Maxali 相同的方法,但使用了一个名为 lodash 的 JavaScript 库。它对于过滤数组和对象很有用,无需编写自己的过滤代码。

      我没有保存到二维数组,而是创建了一个 JSON 对象,其中数组作为值,因为我发现在我的 javascript 中拥有可以阅读和理解的键很有用。看看 lodash,它可能对你今天需要的东西有点过分,但对明天可能有用。

      https://lodash.com/

      <!DOCTYPE html>
      <html>
      
      <head>
        <script src="https://raw.github.com/lodash/lodash/4.0.0/dist/lodash.js"></script>
        <!-- downloaded from https://lodash.com -->
        <script>
          var files = ['home_01.ai', 'home_02.ai', 'home_03.ai', 'imprint_01.ai', 'imprint_02.ai'];
      
          var getPrefixFn = function(file) {
            return file.substr(0, file.indexOf('_'));
          };
          var prefixes = _.map(files, getPrefixFn);
          var uniquePrefixes = _.uniq(prefixes);
          var groupedFiles = {};
      
          _(files).forEach(function(file) {
            _(uniquePrefixes).forEach(function(prefix) {
              if (groupedFiles[prefix] == null) groupedFiles[prefix] = []; // create a new group if it doesnt exist
              if (file.indexOf(prefix) === 0) {
                groupedFiles[prefix].push(file);
              }
            });
          });
      
          console.log(groupedFiles);
        </script>
      
      </head>
      
      <body>
      </body>
      
      </html>

      如果二维数组更容易处理,那么试试这个:

      <!DOCTYPE html>
      <html>
      
      <head>
        <script src="https://raw.github.com/lodash/lodash/4.0.0/dist/lodash.min.js"></script>
        <!-- downloaded from https://lodash.com -->
        <script>
          var files = ['home_01.ai', 'home_02.ai', 'home_03.ai', 'imprint_01.ai', 'imprint_02.ai'];
      
          var getPrefixFn = function(file) {
            return file.substr(0, file.indexOf('_'));
          };
          var prefixes = _.map(files, getPrefixFn);
          var uniquePrefixes = _.uniq(prefixes);
          var groupedFiles = [];
      
          for (var index = 0, length = uniquePrefixes.length; index < length; index += 1) {
            var prefix = uniquePrefixes[index];
            groupedFiles[index] = [];
            for (var fileIndex = 0, fileLength = files.length; fileIndex < fileLength; fileIndex += 1) {
              if (files[fileIndex].indexOf(prefix) === 0) {
                groupedFiles[index].push(files[fileIndex]);
              }
            };
          }
      
          console.log(groupedFiles);
        </script>
      </head>
      
      <body>
      
      </body>
      
      </html>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-13
        • 2020-06-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多