【问题标题】:Create multi-dimensional array index in Javascript?在Javascript中创建多维数组索引?
【发布时间】:2012-12-20 21:46:34
【问题描述】:

我有一个 ajax 请求返回给我一个大致如下所示的对象:

[
 {category: "Test Category", id: "1", name: "Test",  language: "English"},
 {category: "Test Category", id: "2", name: "Test2", language: "English"},
 {category: "A test",        id: "3", name: "Test3", language: "Spanish"},
 {category: "Test Category", id: "4", name: "Test4", language: "Spanish"}
]

基本上我需要一种方法来执行以下操作:

  • 列出所有仅以英语或西班牙语存在的类别
  • 列出以指定语言存在的所有 ID
  • 列出指定类别中存在的所有 ID

现在我相当确定最好的方法是创建我自己的临时数组来存放这些数据,但我对 Javascript 没有足够的信心编写正确的循环来获取这些数据。我知道在 PHP 中我会在循环时执行类似 $category['Test Category'][] = 3 的操作。

我的想法是我需要能够根据用户选择按英语过滤然后按其中的类别过滤事物。

有人能指出正确的方向吗?

【问题讨论】:

  • 听起来工作量很大。相反,请使用 underscore.js - underscorejs.org。您可以使用过滤器、采摘、映射等。
  • 你可以像在 PHP 中那样做,除了 $arr[] = $xarr.push(x)
  • 不要忘记arr = arr || [],如果它不存在,它会创建一个新数组。
  • 或者如果你使用jquery,使用jquery grep api.jquery.com/jQuery.grep

标签: javascript jquery


【解决方案1】:

在任务中使用下划线的一些方法: http://underscorejs.org

var data = [
 {category: "Test Category", id: "1", name: "Test",  language: "English"},
 {category: "Test Category", id: "2", name: "Test2", language: "English"},
 {category: "A test",        id: "3", name: "Test3", language: "Spanish"},
 {category: "Test Category", id: "4", name: "Test4", language: "Spanish"}
]

// Filter by spanish
var output = _.where(data, {"language":"Spanish"});

// Filter by category
var output = _.where(data, {"category":"A test"});

// List specific category ids
var output = _.pluck(_.where(data, {"category":"A test"}), "id");

// List category names
var output = _.pluck(_.where(data, {"language":"English"}), "category");

// Group by languages
var output = _.groupBy(data, function(value) { 
  return value.language
});
output["English"];

【讨论】:

  • 你是谁?约会经纪人?因为你让我爱上了underscore.js ;-)
  • 不不,我同意 Jan 的观点。我可以使用这个 :)
  • _.invoke 的意义何在?它看起来像 _.mapeval
  • 更像是带有 'eval' 的 '_.each'。下划线是所有关于方便和简洁的东西,您在早期学到的一件事是您几乎可以使用 _.each 完成所有操作,但不应该这样做。
【解决方案2】:

既然你在标签中包含了 jQuery,我想我会使用它:

//All categories with English or spanish language (categories is the array)
$.grep(categories, function(c) { return c.language=='English' || c.language == 'Spanish'; });

【讨论】:

    【解决方案3】:

    使用 vanilla JS,其中 json 是您的原始数组,您可以使用:

    function filterJson(attr, obj) {
        var attrList = [],
            match,
            tempAttr,
            i;
    
        for (i = 0; i < json.length; i += 1) {
            match = true;
    
            for (tempAttr in obj) {
                if (!obj[tempAttr].test(json[i][tempAttr])) {
                    match = false;
                    break;
                }
            }
    
            if (match) attrList.push(json[i][attr]);
        }
    
        return attrList;
    }
    

    并像这样使用它:

    “列出所有仅以英语或西班牙语存在的类别”

    filterJson('category', {
        language: /(English|Spanish)/
    });
    // => ["Test Category", "Test Category", "A test", "Test Category"] 
    

    “列出所有以指定语言存在的 ID”

    filterJson('id', {
        language: /English/
    });
    // => ["1", "2"] 
    

    “列出指定类别中存在的所有 ID”

    filterJson('id', {
        category: /Test Category/
    });  
    // => ["1", "2", "4"] 
    

    【讨论】:

      【解决方案4】:

      如果您可以依靠一些关于数据始终为真的假设——例如,您将永远只有类别:、id:、名称:和语言:,并且永远不会有冒号或名称或类别中的任何地方的逗号——那么我实际上建议将所有信息粘贴到单个字符串中并使用 RegExp 来查找它。

      例如:

      [
       "category:Test Category, id:1, name:Test,  language:English",
       "category:Test Category, id:2, name:Test2, language:English",
       "category:A test,        id:3, name:Test3, language:Spanish",
       "category:Test Category, id:4, name:Test4, language:Spanish"
      ]
      

      现在,要查找条目的值,请使用 RegExp.match()。

      var m = /^category:([^,]+)\s+id:(\d+),\s+name:([^,]+),\s+language:(.+)$/i;
      // m[1] = Test Category
      // m[2] = 1;
      // m[3] = Test2
      // m[4] = Spanish
      

      您可以使用测试进行搜索。

      function my_filter(criteria) {
          var results = [];
          var re = new RegExp(criteria);
          for (var i=0; i<array.length; i++) {
              if (array[i].test(re))
                  results.push(array[i]);
          }
          return results;
      }
      var english_array = my_filter('language:english');
      var atest_array = my_filter('category:a test');
      

      【讨论】:

      • 你能解释一下你提出这个解决方案的逻辑吗?这是不同的,我很好奇它的好处。
      • Regex 解析功能强大,更重要的是... native 在浏览器中,因此它可能比复杂的 javascript 解析要快得多。如果需要,只需更改正则表达式即可轻松匹配多个条件。每当我处理相对简单的数据时,我发现在本地处理字符串会更容易、更快捷。
      【解决方案5】:

      神奇的 Google 术语是“map”和“reduce”。

      var data = [...the JSON data parsed with JSON.parse() if necessary...]
      
      var categoriesInEnglish = data.reduce(function(accumulator, category) {
          if(category.language = 'English') {
              accumulator.push(category.id);
          }
      });
      

      http://www.mrspeaker.net/2011/05/02/conventional-interfaces/http://www.mrspeaker.net/2011/04/27/reducing-map/

      【讨论】:

      • 第一次通话时的accumulator 是什么?我怀疑这是一个空数组。
      • 这是答案数组。如果你追求最终的兼容性,jQuery 的 $.map() 和 $.grep() 可能是更简单的实现。
      • 这行不通。第一次调用回调时,它的第一个参数是数组的第一个元素。此外,在每个后续调用中,accumulatorundefined,引发 TypeError。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 2012-05-14
      • 1970-01-01
      相关资源
      最近更新 更多