【问题标题】:Find item in array using weighed probability and a value使用加权概率和值在数组中查找项目
【发布时间】:2017-02-21 11:34:12
【问题描述】:

上周我在做一个简单的程序时遇到了一些问题,这里有人帮助了我。现在我遇到了另一个问题。 我目前有这个代码:

var findItem = function(desiredItem) {
    var items = [
        { item: "rusty nail", probability: 0.25 },
        { item: "stone", probability: 0.23 },
        { item: "banana", probability: 0.20 },
        { item: "leaf", probability: 0.17 },
        { item: "mushroom", probability: 0.10 },
        { item: "diamond", probability: 0.05 }
    ];
    var possible = items.some( ({item, probability}) => 
          item === desiredItem && probability > 0 );
    if (!possible) {
        console.log('There is no chance you\'ll ever find a ' + desiredItem);
        return;
    }
    var sum = items.reduce( (sum, {item, probability}) => sum+probability, 0 );
    while (true) {
        var value = Math.random() * sum;
        var lootedItem = items.find( 
                ({item, probability}) => (value -= probability) <= 0 ).item;
        if (lootedItem === 'diamond') break;
        console.log("Dang! A " + lootedItem + " was found...");
    }
    console.log("Lucky! A " + desiredItem + " was found!");
}

findItem('diamond');

现在我想通过将另一个名为 category 的值添加到 items 数组来对此进行扩展。我希望类别具有2510 的值。因此,假设diamond 项目将属于category: 10,并且当findItem 被执行时,只能找到属于同一类别的项目。我已经尝试了几天,但似乎无法理解它。也许有人可以帮助我朝着正确的方向前进?提前致谢

【问题讨论】:

  • 使用filter 将您的搜索限制在给定的类别?
  • 您的意思是 can be found 只能针对该类别出现“Dang!”消息,而应完全忽略所有其他项目?
  • 谢谢,我会调查的!
  • 是的 trincot,这正是我要找的! :)

标签: javascript arrays probability


【解决方案1】:

您可以对该代码使用此更新:

// Pass the item list and the desired category as arguments:
var findItem = function(items, category, desiredItem) {
    // apply filter to items, so only those of the given category remain:
    items = items.filter( item => item.category == category );
    // rest of code remains the same:
    var possible = items.some( ({item, probability}) => 
          item === desiredItem && probability > 0 );
    if (!possible) {
        console.log('There is no chance you\'ll ever find a ' + desiredItem);
        return;
    }
    var sum = items.reduce( (sum, {item, probability}) => sum+probability, 0 );
    var t = 10;
    while (true) {
        var value = Math.random() * sum;
        var lootedItem = items.find( 
                ({item, probability}) => (value -= probability) <= 0 ).item;
        if (lootedItem === desiredItem) break; // fixed this condition!
        console.log("Dang! A " + lootedItem + " was found...");
        t--; if (t <= 0) throw "loop";
    }
    console.log("Lucky! A " + desiredItem + " was found!");
}

// Define items here with their category
var items = [
    { item: "rusty nail", probability: 0.25, category:  2 },
    { item: "stone",      probability: 0.23, category:  2 },
    { item: "banana",     probability: 0.20, category:  2 },
    { item: "leaf",       probability: 0.17, category:  5 },
    { item: "mushroom",   probability: 0.10, category:  5 },
    { item: "diamond",    probability: 0.05, category: 10 }
];

// Call function with extra arguments:
findItem(items, 5, 'mushroom');

console.log('second run:');
// This will obviously give a hit immediately, as there is only one possible item:
findItem(items, 10, 'diamond');

变化如下:

  • 向您的函数传递更多参数:项目列表和所需类别
  • 对项目列表应用过滤器作为函数中的第一个操作
  • 修复了与 lootedItem 测试有关的问题 - 它已硬编码“钻石”。
  • 在函数外部定义项目列表并将类别值添加到每个元素。
  • 调整函数调用以传递额外的参数。

【讨论】:

  • 非常感谢您,感谢您解释每一点的作用。我觉得我现在对编码了解得更多了!
【解决方案2】:

你想要这样的东西吗?

var items = [ { item: "rusty nail", probability: 0.25, category: 10 }
            , { item: "stone",      probability: 0.23, category:  5 }
            , { item: "banana",     probability: 0.20, category:  2 }
            , { item: "leaf",       probability: 0.17, category:  5 }
            , { item: "mushroom",   probability: 0.10, category:  2 }
            , { item: "diamond",    probability: 0.05, category: 10 }
            ];

findItem("diamond", items);

function findItem(needle, haystack) {
    var item = haystack.find(thing => thing.item === needle &&
                                       thing.probability > 0);

    if (item) {
        var category = item.category;
        var items = haystack.filter(thing => thing.category === category);
        var sum = items.reduce((sum, thing) => sum + thing.probability, 0);

        var value = sum * Math.random();
        var loot = items.find(thing => (value -= thing.probability) <= 0).item;

        while (loot !== needle) {
            value = sum * Math.random();
            console.log("Dang! A " + loot + " was found...");
            loot = items.find(thing => (value -= thing.probability) <= 0).item;
        }

        return console.log("Lucky! A " + needle + " was found!");
    }

    console.log("There's no chance that you'll ever find a " + needle);
}

与您的代码的唯一主要区别是我使用filter 来限制搜索。

【讨论】:

    猜你喜欢
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    • 2019-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多