【问题标题】:set nested object properties based on another property根据另一个属性设置嵌套对象属性
【发布时间】:2014-03-06 18:51:44
【问题描述】:

我想计算字符在文本中出现的次数,然后显示每个字符的总数。我的主要问题是第一部分。

这是我目前的代码快照:

//define text and characters to be searched for
var theArticle = document.getElementById('theText'),
    docFrag = document.createDocumentFragment(),
    theText = theArticle.innerText,
    characters = {
    a: {
        regExp: /a/g,
        matches: [],
        count: 0
    },
    b: {
        regExp: /b/g,
        matches: [],
        count: 0
    },
    c: {
        regExp: /c/g,
        matches: [],
        count: 0
    }

    etc…
}

for (var key in characters) {
    if (characters.hasOwnProperty(key)) {
        var obj = characters.key;
        for (var prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                matches = theText.match(regExp); // pretty sure my problem is here
                count = matches.length; // and here
            }
        }
    }
}

我想遍历所有字符以根据regExp 设置matches 的值,根据matches 的长度设置count 的值。

这个问题的最佳答案是我最接近解决我的问题。 Access / process (nested) objects, arrays or JSON

【问题讨论】:

  • 我已经发现了一些错误:1)不需要检查:if (characters.hasOwnProperty(key)) 在您的 for in 循环中。 2) 您不能使用点符号访问变量属性:var obj = characters.key; 应该是 var obj = characters[key];。 3) 同样,无需检查:if (obj.hasOwnProperty(prop))。纠正这些事情(主要是#2),它应该可以按预期工作。
  • 嗯,我认为解决了它,但我想我在 Chrome 控制台中得到了误报。

标签: javascript regex loops object properties


【解决方案1】:

应该对您的代码进行几处更改:

  1. 无需检查:if (characters.hasOwnProperty(key)) 在您的 for in 循环中。
  2. 您不能使用点符号访问变量属性:var obj = characters.key; 应该是 var obj = characters[key];
  3. 同样,无需检查:if (obj.hasOwnProperty(prop))
  4. 如果您尝试操作角色对象属性,则需要访问对象的属性,而不仅仅是键入键名。

纠正这些事情(主要是#2),它应该可以按预期工作。

但是,我会像这样完全重组您的功能实现:

我将首先简单地定义一个字符串数组:

var characters = ['a','b','c','asd'];

然后编写一个通用函数来处理您的功能:

function findCharsInString(array, string) {
    // map a "results" function to each character in the array
    return array.map(function(c) {
        // make a check to ensure we're working with a string that is only one character
        if (typeof c === 'string' && c.length === 1) {
            // create a RegExp from each valid array element
            var matches = string.match(RegExp(c, 'g'));
            // return an anonymous results object for each character
            return {
                matches: matches,
                count: matches.length
            };
        } else { // if there is an invalid element in the array return something
            return 'Invalid array element.';
        }
    });
}

并将其应用于您的 characters 数组和 theText 字符串:

var theText = 'asjdbasccshaskjhsa';
console.log(findCharsInString(characters, theText));

日志:

[
    {
        matches:
            ["a","a","a","a"],
        count:
            4
    },
    {
        matches:
            ["b"],
        count:
            1
    },
    {
        matches:
            ["c","c"],
        count:
            2
    },
    "Invalid array element."
] 

【讨论】:

  • 这太棒了。谢谢你。你怎么能包含特殊字符,例如不间断空格和标点符号?
  • 如果您超出了基本的字母数字范围,我会看一下 here 以在 RegExp(c, 'g') 中转义 c。然后,您还需要删除字符数组的长度检查。
  • 再次,太棒了,谢谢。我将此标记为答案。我唯一需要更改的是删除长度检查(就像你建议的那样),我在匿名结果对象的顶部添加了 character: c, 以使其不那么匿名。另外,我似乎无法逃脱?
  • 没关系?。如果你使用'\\u003f',那么它工作得很好。