【问题标题】:Set data structure of Java in javascript/jQuery在 javascript/jQuery 中设置 Java 的数据结构
【发布时间】:2021-01-04 10:50:44
【问题描述】:

有没有办法在javascript中创建像java一样的Set数据结构(唯一集合)?

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    对于一组字符串,我只会使用值为 true 的对象。

    var obj = {};
    obj["foo"] = true;
    obj["bar"] = true;
    
    if(obj["foo"])
    {
      // foo in set
    }
    

    这基本上是 HashSet 在 Java 中的工作方式,假设 JavaScript 对象被实现为哈希表(这是典型的)。

    【讨论】:

    • 那么如何从那个集合中移除一个对象呢? obj["foo"]=null?还是 obj["foo"]=false?
    • @Eran、delete obj["foo"]delete obj.foo
    • 感谢你教了一只老狗一个新技巧 :) 这太棒了,我从未在 JS 中遇到过,不过让我回到了我的 C++ 时代......
    • @Eran,是的。您可能知道,它在 JavaScript 中完全不同,因为它是垃圾收集的并且没有析构函数。
    【解决方案2】:

    我编写了一个类似于 Java 的 HashSet 的哈希集的 JavaScript 实现。它允许将任何对象(不仅仅是字符串)用作集合成员。它基于哈希表的键。

    http://code.google.com/p/jshashtable/downloads/list

    我保证很快就会有文档。现在,源代码应该很清楚地为您提供了 API,下面是一个示例:

    var s = new HashSet();
    var o1 = {name: "One"}, o2 = {name: "Two"};
    s.add(o1);
    s.add(o2);
    s.add(o2);
    s.values(); // Array containing o1 and a single reference to o2
    

    【讨论】:

      【解决方案3】:

      虽然这似乎是一个常见问题,我发现似乎是支持对象的a good Set class on the net,但我想要一个更简单的,最后自己写了一个......以防其他人发现它有用...... .

      /**
       * A Javascript Class that represents a set of unique values
       * 
       * Usage:
       * 
       * var s = new jsSet();
       * 
       * s.add('a1'); s.add('a2');
       * 
       * s.list(); >> ['a1','a2']
       * 
       * s.remove('a1'); s.list(); >> ['a2']
       * 
       * s.contains('a1') >> false
       * 
       * s.contains('a2') >> true
       * 
       * can be chained
       * s.add(null).add('hello');
       * 
       * add array
       * s.addAll([ null, 'a', 'b' ]);
       * 
       * remove array
       * s.addAll([ null, 'a', 'b' ]);
       * 
       * retrieve the elements as a list
       * s.list();
       * 
       * size of the set
       * s.size();
       * 
       */
      function jsSet() {
      
          // null can also be an element of the set, but needs
          // a separate indication to differentiate it from
          // the string "null" as well
          this.isNullAdded = false;
      
          // private member variable hence no 'this'
          var map = {};
      
          //  Scope for optimization
          //  could be cached instead of generating each time
          //  this.uniqueList = [];
      
          //  returns true if the element is in this set, false otherwise
          this.contains = function(key) {
      
              if (key === null)
                  return this.isNullAdded;
              else if (key === undefined)
                  return false;
              else
                  return map[key] ? true : false;
          };
      
          //  adds the element to the set
          this.add = function(val) {
      
              if (val === null)
                  this.isNullAdded = true;
              else if (val !== undefined)
                  map[val] = true;
              return this;
          };
      
          //  adds all the elements of the array to the set
          this.addAll = function(val) {
      
              if (val !== null && val !== undefined && val instanceof Array) {
                  for ( var idx = 0; idx < val.length; idx++) {
                      this.add(val[idx]);
                  }
              }
              return this;
          };
      
          //  removes the specified element from the set
          this.remove = function(val) {
              if (val === null)
                  this.isNullAdded = false;
              else if (val !== undefined)
                  delete map[val];
              return this;
          };
      
          //  removes all the element in the array from the set
          this.removeAll = function(val) {
      
              if (val !== null && val !== undefined && val instanceof Array) {
                  for ( var idx = 0; idx < val.length; idx++) {
                      console.log('val: %s:%s', idx, val[idx]);
                      this.remove(val[idx]);
                  }
              }
              return this;
          };
      
          //  empties the set of all values
          this.clear = function() {
      
              this.isNullAdded = false;
              map = {};
              return this;
          };
      
          //  returns the number of elements in the set
          this.size = function() {
      
              return this.list().length;
          };
      
          //  returns true if the set is empty, false otherwise
          this.isEmpty = function() {
      
              return this.list().length > 0? false: true;
          };
      
          //  returns the elements of the set as a list
          this.list = function() {
              var arr = [];
      
              if (this.isNullAdded)
                  arr.push(null);
      
              for (o in map) {
                  // protect from inherited properties such as
                  //  Object.prototype.test = 'inherited property';
                  if (map.hasOwnProperty(o))
                      arr.push(o);
              }
              return arr;
          };
      };
      

      【讨论】:

      • 如果我们不需要Set中的空值,那么我们可以在添加所有元素后执行remove(null)。
      【解决方案4】:

      在现代浏览器中,我会使用仅使用键方法的 Map。例如:

      • 新设置:let mySet = new Map();
      • 添加元素:mySet.set(element, 1)
      • 删除元素:mySet.delete(element)
      • 包含元素:mySet.has(element)

      如果您不想看到 Map 实现,可以制作自己的包装器。这种方式就是Java HashSet的实现方式,它使用了HashMap并且只使用了关键方法。

      【讨论】:

        【解决方案5】:

        Javascript 现在提供(es6 的一部分)Set Api,可用于创建唯一集合。

        var set = new Set([1,1,2,3]);
        set.add(1);
        set.add(4); 
        

        欲了解更多信息,请访问 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set

        【讨论】:

          猜你喜欢
          • 2015-01-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-05
          • 2015-11-15
          相关资源
          最近更新 更多