循环数组并与其他数组进行比较

时间:2014-11-05 12:57:48

标签: javascript arrays

我试图创建一个将句子作为参数的代码,将该句子拆分成一个单词数组,然后创建一个循环,检查这些单词是否与其他数组中的单词匹配。

在下面的示例中,我有一个包含单词" ski"的句子。这意味着返回值应为categories.type3

如何让循环检查呢?我可以在不同类别之间切换功能吗? (即:如果某个单词不在action中,请查看adventure,依此类推)。

var categories = {

    type1: "action",
    type2: "adventure",
    type3: "sport"
}

var Sentence = "This sentence contains the word ski";

var sport = ["soccer", "tennis", "Ski"];
var action = ["weapon", "explosions"];
var adventure = ["puzzle", "exploring"];

var myFreeFunc = function (Sentence) {

    for (var i = 0; i < arrayLength; i++) {

        if (typeArr[i] == word) {

        }
    }
}

3 个答案:

答案 0 :(得分:3)

您似乎想知道哪些类别符合该句子。

首先,摆脱无意义的type1等标识符,并将您的固定数据重新排列到直接表示所需数据的对象中,特别是Map个键/值对,其中每个key是“类别”名称,每个值都是与该类别关联的Set个关键字:

var categories = new Map([
    ['action', new Set(['weapon', 'explosions'])],
    ['adventure', new Set(['puzzle', 'exploring'])],
    ['sport', new Set(['soccer', 'tennis', 'ski'])]
]);

[NB:SetMap是新的ES6功能。 Polyfills是available]

现在,您可以迭代categories地图以获取类别列表,并查看每个类别的内容以查找关键字:

function getCategories(sentence) {
    var result = new Set();
    var words = new Set(sentence.toLowerCase().split(/\b/g)); /* "/b" for word boundary */
    categories.forEach(function(wordset, category) {
        wordset.forEach(function(word) {
             if (words.has(word)) {
                 result.add(category);
             }
        });
    });
    return result.values();  // NB: Iterator interface
}

注意:我已经避免使用for .. of,因为无法填充,Set.prototype.forEachMap.prototype.forEach可以。

答案 1 :(得分:1)

我会重写代码(你应该总是组合var语句)。

我添加了一个小fiddle snippet,我将如何重写该功能。举个例子,您可以如何迭代数据。当然,您应该查看其他帖子以优化此代码剪辑(例如修复多个空格!)。

// make sure, your dictionary contains lower case words
var categories = {
    action: ["soccer", "tennis", "ski"],
    adventure: ["weapon", "explosions"],
    sport: ["puzzle", "exploring"]
}

var myFreeFunc = function myFreeFunc(Sentence) {

    // iterates over all keys on the categories object
    for (var key in categories) {

        // convert the sentence to lower case and split it on spaces
        var words = Sentence.toLowerCase().split(' ');

        // iterates the positions of the words-array            
        for (var wordIdx in words)
        {
            // output debug infos
            console.log('test:', words[wordIdx], categories[key], categories[key].indexOf(words[wordIdx]) != -1, '('+categories[key].indexOf(words[wordIdx])+')');

            // lets the array function 'indexOf' check for the word on position wordIdx in the words-array
            if (categories[key].indexOf(words[wordIdx]) != -1 ) {
                // output the found key
                console.log('found', key);

                // return the found key and stop searching by leaving the function
                return key;
            }

        }//-for words


    }//-for categories

    // nothing found while iterating categories with all words
    return null;
}

剥离了功能部分片段(没有注释,没有多余的空格,没有console.log):

var myFreeFunc = function myFreeFunc(Sentence) {
    for (var key in categories) {
        var words = Sentence.toLowerCase().split(' ');          
        for (var wordIdx in words)
        {
            if (categories[key].indexOf(words[wordIdx]) != -1 ) {
                return key;
            }
        }
    }
    return null;
}

累积了评论中涵盖的主题

  • 检查对象是否确实拥有该属性:obj.hasOwnProperty(prop)
  • 按字边界分割字符串,如Alnitak所述(使用RegExp):/ \ b / g
  • 收集多个匹配的类别

段:

var myFreeFunc = function myFreeFunc(Sentence) {
    var result = []; // collection of results.
    for (var key in categories) {
        if (categories.hasOwnProperty(key)) { // check if it really is an owned key
            var words = Sentence.toLowerCase().split(/\b/g);  // splitting on word bounds        
            for (var wordIdx in words)
            {
                if (categories[key].indexOf(words[wordIdx]) != -1 ) {
                    result.push(key);
                }
            }
        }
    }
    return result;
}

答案 2 :(得分:0)

一种简单的方法是这样做:

function determineCategory(word){

    var dictionnary = {
       // I assume here you don't need category1 and such

        action: ["weapon", "explosions"],
        aventure: ["puzzle", "exploring"],
        sport: ["soccer", "tennis", "ski"]
    }
    var categories = Object.keys(dictionnary);
    for(var i = 0; i<categories.length; i++){
        for(var j = 0; j<categories[i].length;j++){
            var wordCompared = dictionnary[categories[i]][j];
            if(wordCompared == word){
                return categories[i];
            }
        }
    }
    return "not found"; 
}

var sentence = "This sentence contains the word ski";
var words = sentence.split(" "); // simple separation into words
var result = [];
for(var i=0; i<words.length; i++){
    result[i] = determineCategory(words[i]);
}

关于这种方法的几点说明:

  • 它需要你改变你现有的结构(我不知道它是否可能)
  • 它对你的句子分裂没有太大作用(只使用空格)。有关更聪明的方法,请参阅Alnitak的答案,或寻找标记化 / 词形化方法。
  • 由您来决定当一个单词不属于某个类别时该怎么做(现在,它只是存储“未找到”。