【问题标题】:Remove array elements based on dynamic value Javascript基于动态值Javascript删除数组元素
【发布时间】:2017-03-21 18:31:37
【问题描述】:

我的 Ember 应用程序中有 2 个数组,一个数组包含一串 ID,另一个包含 Ember 对象。

我想将 Ember 对象发送到一个函数,从存储在浏览器中的 cookie 中获取 ID 数组,然后如果 ID 属性对应于我的 IDS 数组中的字符串,则过滤掉 Ember 对象。

我试图为此使用过滤器,但每次它只带回 Ember 对象的完整列表,即使 ID 字符串数组中保存有 ID。这是我的 Ember 组件中的代码..

init () {
        this._super(...arguments);

this.get('userNotificationServices').fetchActiveUserNotifications().then(result => {
            this.updatedArray = this.filterArray(result);
            this.set('activeNotifications', result);
        });

    },

filterArray(currentActiveNotifications) {
    var ids;
    var currentNonDimissedNotifications;
    if (this.getCookie("dismissed-notifications")) {
        ids = this.getCookie("dismissed-notifications").split(',');
        currentNonDimissedNotifications = currentActiveNotifications.filter(function (obj) {
            for (var id in ids) {
                return obj.id !== id;
            }
        });
    }
    return currentNonDimissedNotifications;
}

【问题讨论】:

  • 使用set方法this.set('updatedArray', this.filterArray(result));而不是像这样直接赋值this.updatedArray = this.filterArray(result);

标签: javascript arrays ember.js


【解决方案1】:

你的filter有两个问题:

currentNonDimissedNotifications = currentActiveNotifications.filter(function (obj) {
    for (var id in ids) {
        return obj.id !== id;
    }
});
  1. 它总是返回 first 检查的结果;它从不进行后续检查,因为您无条件使用return

  2. 您使用了for-in,这意味着id 将是每个条目的索引,而不是它的值。更多关于循环数组的信息,以及为什么for-in 在大多数情况下都不正确,请参阅my answer here

我们只想在找到匹配项(我们可以立即停止)或循环遍历整个 ID 数组并且我们想要正确循环时返回。

可能是这样的:

currentNonDimissedNotifications = currentActiveNotifications.filter(function (obj) {
    for (var i = 0; i < ids.length; ++i) { // Note loop
        if (obj.id === ids[i]) {
            // Found it, so we want to filter it out
            return false;
        }
    }
    // Didn't find it, so keep it
    return true;
});

现场示例:

var currentActiveNotifications = [
  {id: 1},
  {id: 2},
  {id: 3}
];
var ids = [2, 3];
var currentNonDimissedNotifications = currentActiveNotifications.filter(function (obj) {
    for (var i = 0; i < ids.length; ++i) { // Note loop
        if (obj.id === ids[i]) {
            // Found it, so we want to filter it out
            return false;
        }
    }
    // Didn't find it, so keep it
    return true;
});
console.log(currentNonDimissedNotifications);

...但是数组有一个方便的函数indexOf,它可以让我们检查一个值是否在数组中(较新版本的JavaScript也有includes)。所以我们可以使用它:

currentNonDimissedNotifications = currentActiveNotifications.filter(function (obj) {
    return ids.indexOf(obj.id) === -1;
});

现场示例:

var currentActiveNotifications = [
  {id: 1},
  {id: 2},
  {id: 3}
];
var ids = [2, 3];
var currentNonDimissedNotifications = currentActiveNotifications.filter(function (obj) {
    return ids.indexOf(obj.id) === -1;
});
console.log(currentNonDimissedNotifications);

或使用较新的includes

currentNonDimissedNotifications = currentActiveNotifications.filter(function (obj) {
    return !ids.includes(obj.id);
});

现场示例:

var currentActiveNotifications = [
  {id: 1},
  {id: 2},
  {id: 3}
];
var ids = [2, 3];
var currentNonDimissedNotifications = currentActiveNotifications.filter(function (obj) {
    return !ids.includes(obj.id);
});
console.log(currentNonDimissedNotifications);

【讨论】:

  • 谢谢,有没有办法做到这一点,所以如果我们在两个数组中都有多个 id,它会从父数组中删除每一个?
  • 如果我在第一个数组中说 ID 1,2,在第二个数组中说 ID 1,2,我想返回一个空数组,这可能吗?
  • @NickPocock:这就是上面所做的。我添加了现场示例(并修复了 includes 一个,我缺少了一个 !)。
【解决方案2】:

你不应该使用for循环来过滤对象,因为return obj.id !== id;总是会返回true,而且它也只检查第一个id。

尝试使用 indexOf:

currentNonDimissedNotifications = currentActiveNotifications.filter(function(obj) {
  return ids.indexOf(obj.id) === -1
});

【讨论】:

    猜你喜欢
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 2021-03-28
    • 1970-01-01
    • 2017-05-25
    • 1970-01-01
    • 2010-12-26
    • 2014-11-01
    相关资源
    最近更新 更多