【问题标题】:Remove certain elements from map in Javascript在Javascript中从地图中删除某些元素
【发布时间】:2013-09-07 02:22:22
【问题描述】:

如何从以下映射中删除所有键/值对,其中 键以 X 开头

var map = new Object(); 
map[XKey1] = "Value1";
map[XKey2] = "Value2";
map[YKey3] = "Value3";
map[YKey4] = "Value4";

编辑

有没有办法通过正则表达式,可能使用 ^ 。 类似于 map[^XKe],其中 key 以 'Xke' 而不是 'X' 开头

【问题讨论】:

  • delete 带有 for...in 循环
  • @Blazemonger 我认为他们的意图是遍历数组map,如果键以“x”开头,则删除该元素。
  • @user1477388:那么他、她或他们需要解释和澄清这一点,而不是依靠猜测。
  • @DavidThomas 我很清楚,但是...您在下面的回答很好,干得好!
  • XKey1 是不是具有不同值的变量?或者那些应该在map["XKey1"] = "Value1";这样的引号中?

标签: javascript jquery


【解决方案1】:

这样就可以轻松搞定了。

var map = new Object(); 
map['Key1'] = "Value1";
map['Key2'] = "Value2";
map['Key3'] = "Value3";
map['Key4'] = "Value4";
console.log(map);
delete map["Key1"];
console.log(map);

这是删除它的简单方法。

【讨论】:

    【解决方案2】:

    我建议:

    function removeKeyStartsWith(obj, letter) {
        for (var prop in obj) {
            if (obj.hasOwnProperty(prop) && prop[0] == letter){
                delete obj[prop];
            }
        }
    }
    

    JS Fiddle demo.

    顺便说一句,使用 Object-literal 而不是构造函数通常更容易(并且似乎被认为是“更好的做法”),因此以下内容值得展示(即使出于某种原因,您更喜欢 @987654328 @语法:

    var map = {
        'XKey1' : "Value1",
        'XKey2' : "Value2",
        'YKey3' : "Value3",
        'YKey4' : "Value4",
    };
    

    JS Fiddle demo.

    如果你真的想使用正则表达式(但是为什么?),那么下面的工作:

    function removeKeyStartsWith(obj, letter, caseSensitive) {
        // case-sensitive matching: 'X' will not be equivalent to 'x',
        // case-insensitive matching: 'X' will be considered equivalent to 'x'
        var sensitive = caseSensitive === false ? 'i' : '',
            // creating a new Regular Expression object,
            // ^ indicates that the string must *start with* the following character:
            reg = new RegExp('^' + letter, sensitive);
        for (var prop in obj) {
            if (obj.hasOwnProperty(prop) && reg.test(prop)) {
                delete obj[prop];
            }
        }
    }
    
    var map = new Object();
    map['XKey1'] = "Value1";
    map['XKey2'] = "Value2";
    map['YKey3'] = "Value3";
    map['YKey4'] = "Value4";
    console.log(map);
    removeKeyStartsWith(map, 'x', true);
    console.log(map);
    

    JS Fiddle demo.

    最后(至少对于现在而言)一种扩展Object原型的方法允许用户搜索以给定字符串开头、以给定字符串结尾的属性或(通过同时使用startsWith endsWith) 一个给定的字符串(有或没有区分大小写:

    Object.prototype.removeIf = function (needle, opts) {
        var self = this,
            settings = {
                'beginsWith' : true,
                'endsWith' : false,
                'sensitive' : true
            };
        opts = opts || {};
        for (var p in settings) {
            if (settings.hasOwnProperty(p)) {
                settings[p] = typeof opts[p] == 'undefined' ? settings[p] : opts[p];
            }
        }
        var modifiers = settings.sensitive === true ? '' : 'i',
            regString = (settings.beginsWith === true ? '^' : '') + needle + (settings.endsWith === true ? '$' : ''),
            reg = new RegExp(regString, modifiers);
        for (var prop in self) {
            if (self.hasOwnProperty(prop) && reg.test(prop)){
                delete self[prop];
            }
        }
        return self;
    };
    
    var map = {
        'XKey1' : "Value1",
        'XKey2' : "Value2",
        'YKey3' : "Value3",
        'YKey4' : "Value4",
    };
    
    console.log(map);
    map.removeIf('xkey2', {
        'beginsWith' : true,
        'endsWith' : true,
        'sensitive' : false
    });
    console.log(map);
    

    JS Fiddle demo.

    参考资料:

    【讨论】:

    • 谢谢可以通过正则表达式,已经编辑了我的问题。
    • 那么你需要用户 substr
    • @newbie:不,这不会像所写的那样工作,但您可以改用prop.indexOf(letter) === 0。但是,虽然我还没有添加该选项,但我已经发布了一个可以满足您需求的解决方案(据我目前了解),它扩展了 Object 原型。我会尽快添加参考资料和解释(必须先做几件家务,抱歉!XD)。
    • +1:很好的答案。我发现 opts/settings 方法有点过头了,有点像厨房水槽,宁愿使用多种方法(或者确实通过正则表达式进行匹配),但仍然......不能说你没有'不要特意写一个好的答案!
    • @haylem:谢谢!是的,我完全同意你的看法;但上一次迭代的“厨房水槽”风格部分是为了尝试和预测进一步的请求(另外,我非常喜欢让事情易于扩展,我认为就是这种方法)。 =)
    【解决方案3】:

    您可以使用 Object.key 迭代映射键。

    最简单的解决办法是这样的:

    DEMO HERE

    Object.keys(map).forEach(function (key) {
     if(key.match('^'+letter)) delete obj[key];
    });
    

    所以这里是另一个版本的removeKeyStartsWith,正如你所说的那样带有正则表达式:

    function removeKeyStartsWith(obj, letter) {
      Object.keys(obj).forEach(function (key) {
         //if(key[0]==letter) delete obj[key];////without regex
               if(key.match('^'+letter)) delete obj[key];//with regex
    
      });
    }
    
    var map = new Object(); 
    map['XKey1'] = "Value1";
    map['XKey2'] = "Value2";
    map['YKey3'] = "Value3";
    map['YKey4'] = "Value4";
    
    console.log(map);
    removeKeyStartsWith(map, 'X');
    console.log(map);
    

    Regex 的解决方案将满足您的需求,即使您按照您所说的那样使用 letter=Xke 但对于没有 Regex 的其他解决方案,您需要替换:

    Key[0]==letterkey.substr(0,3)==letter

    【讨论】:

    • 谢谢是否可以通过正则表达式,已经编辑了我的问题。
    • key[0]==letter, 如果我的密钥以 'XKe' 而不是 X 开头怎么办
    • @newbie 使用正则表达式的解决方案如果您使用 XKe 作为字母或使用 key.substr(0,3)==letter 而不是 key[0]==letter 将起作用
    • 谢谢。请不要介意,我应该如何在 Jsfiddle 中测试,我选择了所有然后单击运行
    • @newbie 使用浏览器的控制台,你会在那里看到结果
    【解决方案4】:

    前提条件

    假设您的原始输入:

    var map = new Object();
    
    map[XKey1] = "Value1";
    map[XKey2] = "Value2";
    map[YKey3] = "Value3";
    map[YKey4] = "Value4";
    

    并假设一个变量 pattern 将包含您想要过滤的键(例如 "X""Y""prefixSomething"、...)。

    解决方案 1 - 使用 jQuery 过滤并创建新对象

    var clone = {};
    
    $.each(map, function (k, v) {
      if (k.indexOf(pattern) == 0) { // k not starting with pattern
        clone[k] = v;
      }
    });
    

    解决方案 2 - 使用纯 ECMAScript 并创建新对象

    var clone = {};
    
    for (var k in map) {
      if (map.hasOwnProperty(k) && (k.indexOf(pattern) == 0)) {
        clone[k] = map[k];
      }
    }
    

    解决方案 3 - 使用纯 ECMAScript 并使用源对象

    for (var k in map) {
      if (map.hasOwnProperty(k) && (k.indexOf(pattern) == 0)) {
        delete map[k];
      }
    }
    

    或者,在现代浏览器中:

    Object.keys(map).forEach(function (k) {
      if (k.indexOf(pattern) == 0) {
        delete map[k];
      }
    });
    

    更新 - 使用正则表达式进行模式匹配

    如果键 k 以以下字母开头,而不是使用以下内容进行匹配:

    k[0] == letter // to match or letter
    

    如果键 k 以以下字符串开头,则匹配:

    k.indexOf(pattern) // to match a string
    

    您可以改用这个正则表达式:

    new Regexp('^' + pattern).test(k)
    // or if the pattern isn't variable, for instance you want
    // to match 'X', directly use:
    //   /^X/.test(k)
    

    【讨论】:

    • 谢谢是否可以通过正则表达式,已经编辑了我的问题。
    • @newbie:不,不是。或者至少不是你在问题中的意思。但是你可以用正则表达式来做startsWith。我会更新我的答案。
    • 您正在使用 k[0] ,如果字母以 'Xke' 而不是仅 'X' 开头,它会起作用
    • @newbie:请注意,我不建议使用 k[0] 检查第一个字母。这来自大卫的原始答案。我从一开始就建议使用k.indexOf(pattern) == 0,其中模式可以是"Xke" 或任何字符串。它更通用(并且对于非常非常长的键也可能很慢,但这不太可能。
    • @newbie:另外,虽然您可以使用正则表达式,但老实说,我不知道您为什么会在这种情况下使用。我也不建议使用这种方法。
    猜你喜欢
    • 1970-01-01
    • 2019-11-09
    • 2022-08-16
    • 2018-08-08
    • 2018-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多