仅当 Javascript 中尚不存在时才追加数组元素

发布于 2024-12-08 04:50:24 字数 582 浏览 2 评论 0 原文

仅当 Javascript 中尚不存在该元素时,我才需要将其添加到数组中。基本上我将数组视为一个集合。

我需要将数据存储在数组中,否则我只需使用一个可以用作集合的对象。

我编写了以下数组原型,想听听是否有人知道更好的方法。这是一个 O(n) 插入。我希望进行 O(ln(n)) 插入,但是,我没有看到一种简单的方法将元素插入到排序数组中。对于我的应用程序,数组长度会非常小,但我仍然更喜欢遵守公认规则的东西,以获得良好的算法效率:

Array.prototype.push_if_not_duplicate = function(new_element){
    for( var i=0; i<this.length; i++ ){
        // Don't add if element is already found
        if( this[i] == new_element ){
            return this.length;
        }
    }
    // add new element
    return this.push(new_element);
}

I need to add an element to an array only if it is not already there in Javascript. Basically I'm treating the array as a set.

I need the data to be stored in an array, otherwise I'd just use an object which can be used as a set.

I wrote the following array prototype and wanted to hear if anyone knew of a better way. This is an O(n) insert. I was hoping to do O(ln(n)) insert, however, I didn't see an easy way to insert an element into a sorted array. For my applications, the array lengths will be very small, but I'd still prefer something that obeyed accepted rules for good algorithm efficiency:

Array.prototype.push_if_not_duplicate = function(new_element){
    for( var i=0; i<this.length; i++ ){
        // Don't add if element is already found
        if( this[i] == new_element ){
            return this.length;
        }
    }
    // add new element
    return this.push(new_element);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

下壹個目標 2024-12-15 04:50:24

如果我理解正确,您已经有一个已排序的数组(如果您没有已排序的数组,则可以使用 Array.sort 方法对数据进行排序),现在您想向其中添加一个元素(如果该元素尚不存在)数组。我在 二进制插入(使用二进制搜索)方法rel="nofollow">Google 闭包库。相关代码本身看起来像这样,它是 O(log n) 操作,因为二分搜索是 O(log n) 。

function binaryInsert(array, value) {
  var index = binarySearch(array, value);
  if (index < 0) {
    array.splice(-(index + 1), 0, value);
    return true;
  }
  return false;
};

function binarySearch(arr, value) {
  var left = 0;  // inclusive
  var right = arr.length;  // exclusive
  var found;
  while (left < right) {
    var middle = (left + right) >> 1;

    var compareResult = value > arr[middle] ? 1 : value < arr[middle] ? -1 : 0;
    if (compareResult > 0) {
      left = middle + 1;
    } else {
      right = middle;
      // We are looking for the lowest index so we can't return immediately.
      found = !compareResult;
    }
  }
  // left is the index if found, or the insertion point otherwise.
  // ~left is a shorthand for -left - 1.
  return found ? left : ~left;
};

用法是binaryInsert(数组,值)。这也保持了数组的排序。

If I understand correctly, you already have a sorted array (if you do not have a sorted array then you can use Array.sort method to sort your data) and now you want to add an element to it if it is not already present in the array. I extracted the binary insert (which uses binary search) method in the google closure library. The relevant code itself would look something like this and it is O(log n) operation because binary search is O(log n).

function binaryInsert(array, value) {
  var index = binarySearch(array, value);
  if (index < 0) {
    array.splice(-(index + 1), 0, value);
    return true;
  }
  return false;
};

function binarySearch(arr, value) {
  var left = 0;  // inclusive
  var right = arr.length;  // exclusive
  var found;
  while (left < right) {
    var middle = (left + right) >> 1;

    var compareResult = value > arr[middle] ? 1 : value < arr[middle] ? -1 : 0;
    if (compareResult > 0) {
      left = middle + 1;
    } else {
      right = middle;
      // We are looking for the lowest index so we can't return immediately.
      found = !compareResult;
    }
  }
  // left is the index if found, or the insertion point otherwise.
  // ~left is a shorthand for -left - 1.
  return found ? left : ~left;
};

Usage is binaryInsert(array, value). This also maintains the sort of the array.

指尖微凉心微凉 2024-12-15 04:50:24

删除了我的其他答案,因为我错过了数组已排序的事实。

您编写的算法会遍历数组中的每个元素,如果没有匹配项,则会在末尾附加新元素。我认为这意味着您之后正在运行另一种类型。

可以通过使用分治算法来改进整个算法。选择数组中间的一个元素,与新元素进行比较,然后继续,直到找到插入的位置。它会比上面的算法稍快,并且之后不需要排序。

如果您需要帮助制定算法,请随时询问。

Deleted my other answer because I missed the fact that the array is sorted.

The algorithm you wrote goes through every element in the array and if there are no matches appends the new element on the end. I assume this means you are running another sort after.

The whole algorithm could be improved by using a divide and conquer algorithm. Choose an element in the middle of the array, compare with new element and continue until you find the spot where to insert. It will be slightly faster than your above algorithm, and won't require a sort afterwards.

If you need help working out the algorithm, feel free to ask.

酷炫老祖宗 2024-12-15 04:50:24

我之前已经创建了一个(简单且不完整的)Set 类型,如下所示:

var Set = function (hashCodeGenerator) {
    this.hashCode = hashCodeGenerator;
    this.set = {};
    this.elements = [];
};
Set.prototype = {
  add: function (element) {
    var hashCode = this.hashCode(element);
    if (this.set[hashCode]) return false;
    this.set[hashCode] = true;
    this.elements.push(element);
    return true;
  },
  get: function (element) {
    var hashCode = this.hashCode(element);
    return this.set[hashCode];
  },
  getElements: function () { return this.elements; }
};

您只需要为您的对象找到一个好的hashCodeGenerator 函数即可。如果您的对象是基元,则此函数可以返回对象本身。然后,您可以从 getElements 访问器访问数组形式的集合元素。插入的时间复杂度为 O(1)。空间要求为 O(2n)。

I've created a (simple and incomplete) Set type before like this:

var Set = function (hashCodeGenerator) {
    this.hashCode = hashCodeGenerator;
    this.set = {};
    this.elements = [];
};
Set.prototype = {
  add: function (element) {
    var hashCode = this.hashCode(element);
    if (this.set[hashCode]) return false;
    this.set[hashCode] = true;
    this.elements.push(element);
    return true;
  },
  get: function (element) {
    var hashCode = this.hashCode(element);
    return this.set[hashCode];
  },
  getElements: function () { return this.elements; }
};

You just need to find out a good hashCodeGenerator function for your objects. If your objects are primitives, this function can return the object itself. You can then access the set elements in array form from the getElements accessor. Inserts are O(1). Space requirements are O(2n).

时光病人 2024-12-15 04:50:24

如果您的数组是二叉树,则可以通过将新元素放在末尾并将其冒泡到位来以 O(log n) 进行插入。执行重复项检查也需要 O(log n) 时间。

维基百科有很好的解释。

If your array is a binary tree, you can insert in O(log n) by putting the new element on the end and bubbling it up into place. Checks for duplicates would also take O(log n) to perform.

Wikipedia has a great explanation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文