使用加权概率和值查找数组中的项目
Find item in array using weighed probability and a value
上周我在做一个简单的程序时遇到了一些问题,这里有人帮助了我。现在我 运行 遇到了另一个问题。
我目前有这个代码:
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');
现在我想通过向 items
数组添加另一个名为 category
的值来对此进行扩展。我希望类别的值为 2
、5
或 10
。因此,假设 diamond
项目属于 category: 10
,当执行 findItem
时,只能找到属于同一类别的项目。我已经尝试了几天了,但似乎无法理解它。也许有人可以帮助我朝着正确的方向前进?提前致谢
您可以对该代码使用此更新:
// 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
测试的问题 -- 它已 "diamond" 硬编码。
- 在函数外定义项目列表并为每个元素添加类别值。
- 调整函数的调用以传递额外的参数。
你想要这样的东西吗?
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
来限制搜索。
上周我在做一个简单的程序时遇到了一些问题,这里有人帮助了我。现在我 运行 遇到了另一个问题。 我目前有这个代码:
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');
现在我想通过向 items
数组添加另一个名为 category
的值来对此进行扩展。我希望类别的值为 2
、5
或 10
。因此,假设 diamond
项目属于 category: 10
,当执行 findItem
时,只能找到属于同一类别的项目。我已经尝试了几天了,但似乎无法理解它。也许有人可以帮助我朝着正确的方向前进?提前致谢
您可以对该代码使用此更新:
// 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
测试的问题 -- 它已 "diamond" 硬编码。 - 在函数外定义项目列表并为每个元素添加类别值。
- 调整函数的调用以传递额外的参数。
你想要这样的东西吗?
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
来限制搜索。