使用 Javascript Array.Filter 修改原始数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13885866/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 15:02:51  来源:igfitidea点击:

Modify original array with Javascript Array.Filter

javascriptarraysfilterangularjs

提问by jtheis

I want to use Javascript's array.filter to remove items from an array, because the syntax is elegant and readable. However, it seems that filter doesn't modify the original array, it just returns a new array, filtered as you requested. My question is, why doesn't the following work as I expect?

我想使用 Javascript 的 array.filter 从数组中删除项目,因为语法优雅且可读。但是,过滤器似乎不会修改原始数组,它只是返回一个新数组,按照您的要求进行过滤。我的问题是,为什么下面的工作不像我期望的那样工作?

$scope.clearList = function () {
  this.list = this.list.filter(function (item) {
    return item.checked == true;
  });

  //...
}

I would expect that after returning the newly filtered array, this.list would now hold just the filtered set. It does not work like this however. this.list ends up containing exactly the same items. Altering the code to save out the filtered array in an intermediate variable shows that it is indeed filtering correctly.

我希望在返回新过滤的数组后, this.list 现在将只保存过滤后的集合。然而,它不是这样工作的。this.list 最终包含完全相同的项目。更改代码以将过滤后的数组保存在中间变量中表明它确实在正确过滤。

I've done a workaround for now, looping through the filtered version and splicing items out of the original list that should be filtered, but this is inelegant. Am I just thinking about it the wrong way?

我现在已经做了一个解决方法,遍历过滤后的版本并从原始列表中拼接出应该过滤的项目,但这是不雅的。我只是想错了吗?



Sidenote: I'm using Angular.js. I'm unsure it matters at all, but the list comes from the following:

旁注:我正在使用 Angular.js。我不确定这是否重要,但该列表来自以下内容:

  <div class="list" ng-repeat="list in lists">
    <!-- ... -->
    <ul>
      <li ng-repeat="item in list">
        <div>
          <label>
            <input type="checkbox" ng-model="item.checked"/>
            {{item.name}}
          </label>
          <!-- ... -->
        </div>
      </li>
    </ul>
    <button class="btn clear-selected" ng-click="clearList()">
      Remove Selected
    </button>
  </div>


Edit to add debugging info: I've introduced a temp variable just to see whats going on in the debugger.

编辑以添加调试信息:我引入了一个临时变量只是为了查看调试器中发生了什么。

var temp = this.list.filter(function (item) {
  return item.checked == true;
});

this.list = temp;

Before execution, this.List has 5 items, temp is undefined. After the first line is executed, this.List has 5 items, and temp has 2 items. After the last line is executed, this.List has 2 items, temp has 2 items.

执行前,this.List 有 5 项,temp 未定义。第一行执行后,this.List有5项,temp有2项。最后一行执行后,this.List有2项,temp有2项。

However, it seems after this that the UI which is bound to this.list does not update. So something unrelated to filter does seem to be going on.

但是,在此之后绑定到 this.list 的 UI 似乎没有更新。所以一些与过滤器无关的事情似乎正在发生。

采纳答案by jaime

In angular you modify data using the special $scopevariable, and while inside your controller thispoints to the $scopeas the executing context, $scopeis preferred.

在 angular 中,您可以使用特殊$scope变量修改数据,而在您的控制器中this指向$scope作为执行上下文的 ,$scope则是首选。

When the UI doesn't update, it's usually because changes in "models" (or properties of a given scope) are done outside angular. In this case a call to $applyis needed. This notifies angular that something has changed and to update the views.

当 UI 没有更新时,通常是因为“模型”(或给定范围的属性)的更改是在 angular 之外完成的。在这种情况下,$apply需要调用。这会通知 angular 某些内容已更改并更新视图。

However, this doesn't seem to be your issue. I have a working list with minimal changes here http://plnkr.co/edit/Cnj0fEHSmi2L8BjNRAf5?p=preview

但是,这似乎不是您的问题。我有一个工作列表,这里改动很小http://plnkr.co/edit/Cnj0fEHSmi2L8BjNRAf5?p=preview

Here's the contents of the controller and when you call clearList()from the UI, only checked items are left in the list.

这是控制器的内容,当您clearList()从 UI调用时,列表中只剩下选中的项目。

$scope.list = [
  {name: 'one', checked: true},
  {name: 'two', checked: false},
  {name: 'three', checked: true},
  {name: 'four', checked: false}
];

$scope.clearList = function () {
  $scope.list = $scope.list.filter(function(item) {
    return item.checked === true;
  });
};  

Now, I'd recommend passing a list to clearList clearList(list)or even better use Angular filters.

现在,我建议将列表传递给 clearListclearList(list)甚至更好地使用 Angular 过滤器。

回答by RichardTowers

window.list = [1,2,3,4,5,6];
var clearList = function () {
    this.list = this.list.filter(function (item) { return item % 2 === 0; });
};
clearList();
console.log(window.list);

Logs [2, 4, 6]as expected, so I think whatever your bug is is unrelated to filter.

[2, 4, 6]按预期记录,所以我认为无论您的错误是什么都与filter.

Are you sure that the array you're modifying with this.listis the same array that you later come to check?

您确定您正在修改this.list的数组与您稍后要检查的数组相同吗?