[英]How to return a string based on correspondent values summed from an array of strings
As the topic states what is the best way to make it so that when you pass an array of emotions/values, to show the closest value based on a numeric mapping in javascript?.正如该主题所述,最好的方法是什么,以便在传递情绪/值数组时,根据 javascript 中的数字映射显示最接近的值?
Assume that 'Glad' is the same thing as 'Happy', and 'Down' is the same thing as 'Sad'.假设“Glad”与“Happy”是一回事,“Down”与“Sad”是一回事。 Ithe code I've tried seems incredibly lengthy and gets bloated if I add more emotions/states (ie Angry).
我试过的代码看起来非常冗长,如果我添加更多的情绪/状态(即愤怒),它就会变得臃肿。 Aside from the emotions array, any new functions and data structures and variables can be changed/introduced.
除了情绪数组,任何新的函数、数据结构和变量都可以改变/引入。
for example, I can get a list of emotions:例如,我可以得到一个情绪列表:
let emotions = ['Happy','Happy','Sad','Glad','Angry'];
Now I want to return a string that reflects what the 'closest' emotion based on these 5 emotions.现在我想返回一个字符串,该字符串反映基于这 5 种情绪的“最接近”的情绪。
For a better example, let's assume the values correspondent to each emotion is:举个更好的例子,让我们假设每种情绪对应的值是:
Angry = 1, Happy = 2, Sad = 3
愤怒 = 1,快乐 = 2,悲伤 = 3
I was trying something like:我正在尝试类似的东西:
var numb = 0;
for (var i = 0; i < emotions.length; i++) {
if (numb == 'Angry')
numb += 1;
if (numb == 'Happy' || numb == 'Glad')
numb += 2;
if (numb == 'Sad' || numb == 'Down')
numb += 3;
}
var average = numb / emotions.length;
// check which number is closer to
if (average < 1.5)
return 'Angry';
if (average >= 1.5 && < 2.5)
return 'Happy';
if (average > 2.5)
return 'Sad';
if (average == 1.5)
return 'Angry or Happy';
if (average == 2.5)
return 'Happy or Sad';
My expected result based on this list of emotions is:我基于这份情绪列表的预期结果是:
2(*Happy*) + 2(*Happy*) + 3(*Sad*) + 2(*Happy|Glad*) + 1(*Angry*) = 10
Then divide by 5 (the emotions array length), resulting in 2.然后除以 5(情绪数组长度),结果为 2。
So the result that should be returned, as string, is "Happy"
.所以应该作为字符串返回的结果是
"Happy"
。
Let's say I added a fourth type of emotion/feeling... I would be adding more and more of these conditions, and it gets more complicated in the logic checking for the ranges of the numbers.假设我添加了第四种情绪/感觉......我会添加越来越多的这些条件,并且在对数字范围的逻辑检查中变得更加复杂。
I am looking at the list of emotions as a whole, and trying to come up with an overall emotion that represents the whole list.我正在查看整个情绪列表,并试图提出代表整个列表的整体情绪。
What is the best way to do this so that the code looks clean and I can support more states without having the lines of code become too long?这样做的最佳方法是什么,以便代码看起来干净并且我可以支持更多状态而不会使代码行变得太长?
What about something like this:这样的事情怎么样:
Having two object constants:有两个对象常量:
emotionsValues
: Here you assing a value to each emotion you want, like a score to each. emotionsValues
值:在这里你为你想要的每种情绪分配一个值,就像每个情绪的分数一样。
emotionsRank
: Here is the final result of each value, based on average you'll get the result from here. emotionsRank
排名:这是每个值的最终结果,基于平均你将从这里得到的结果。
Now:现在:
Receive the emotions array by parameter.通过参数接收情绪数组。
reduce
it based on the value of each mapped emotion (using emotionsValues
).根据每个映射情感的值来
reduce
它(使用emotionsValues
)。
Get the average获取平均值
See if the floor value + ceil value divided by 2 is equal to the number itself (it means its exactly the half), so use the "emotion or emotion".查看下限值+上限值除以2是否等于数字本身(这意味着它正好是一半),因此使用“情感或情感”。
OR, if not the half, then round to the nearest and get the correct emotion.或者,如果不是一半,则四舍五入到最接近的并获得正确的情绪。 Don't forget to check if average is below 1 or bigger the the last rank (3 in this case)
不要忘记检查最后一个排名的平均值是否低于 1 或更大(在这种情况下为 3)
const emotionsValues = { "Angry": 1, "Happy": 2, "Glad": 2, "Sad": 3, "Down": 3, } const emotionsRank = { 1: "Angry", 2: "Happy", 3: "Sad", } function getEmotion(arrayEmot) { let numb = arrayEmot.reduce((acc, v) => Number(emotionsValues[v]) + acc, 0); let avg = numb / arrayEmot.length; let min = Math.floor(avg) let max = Math.ceil(avg) if ((min + max) / 2 == avg && min != max) { return emotionsRank[min] + " or " + emotionsRank[max] } else { let rounded = avg < 1 ? 1 : avg > 3 ? 3 : Math.round(avg); return emotionsRank[rounded]; } } let emotionsTest = ['Happy', 'Happy', 'Sad', 'Glad', 'Angry']; console.log(getEmotion(emotionsTest)) let emotionsTest2 = ['Happy', 'Happy', 'Sad', 'Sad']; console.log(getEmotion(emotionsTest2))
const emoToValue = { Glad: 1, Happy: 1, Sad: 2 } const valueToEmos = Object.entries(emoToValue).reduce((acc, [emo, val]) => { acc[val] = acc[val] || [] acc[val].push(emo) return acc }, {}) //compute the average: function avgEmotion (emotions) { if (emotions.length == 0) return '' const avg = emotions.reduce((s, em) => s + emoToValue[em], 0) / emotions.length return valueToEmos[Math.round(avg)].join(' or ') } console.log('str', avgEmotion(['Happy', 'Happy', 'Sad', 'Happy'])) //Glad or Happy console.log('str', avgEmotion(['Happy', 'Happy', 'Sad', 'Sad'])) //Sad
You could create a set of indices and get the values by filtering with the index.您可以创建一组索引并通过使用索引过滤来获取值。
function getEmotion(emotions, value) { var values = new Set([value + 0.5, value - 0.5, Math.round(value)]); return emotions.filter((e, i) => values.has(i + 1)).join(' and '); } console.log(getEmotion(['Happy', 'Sad', 'Glad', "Angry"], 1)); console.log(getEmotion(['Happy', 'Sad', 'Glad', "Angry"], 1.5)); console.log(getEmotion(['Happy', 'Sad', 'Glad', "Angry"], 1.7));
This function explicitly checks for the "mid" case and also for out of range values (since it's based on indices):此函数明确检查“中”情况以及超出范围的值(因为它基于索引):
function getEmotion(emotions, value) {
// Out of range
if ( value > emotions.length ) return emotions[emotions.length - 1];
if ( value < 1 ) return emotions[0];
// Determine if decimal is .5
let mid = value % 1 === .5;
// Round the value to the nearest integer
let rounded = Math.round(value);
return mid ? `${emotions[rounded - 2]} or ${emotions[rounded - 1]}` : emotions[rounded - 1];
}
Output:输出:
let emotions = ['Happy', 'Happy', 'Sad', 'Glad', 'Angry'];
console.log(getEmotion(emotions, -23)); // Happy
console.log(getEmotion(emotions, 0)); // Happy
console.log(getEmotion(emotions, 1)); // Happy
console.log(getEmotion(emotions, 2.43)); // Happy
console.log(getEmotion(emotions, 2.5)); // Happy or Sad
console.log(getEmotion(emotions, 3.1)); // Sad
console.log(getEmotion(emotions, 155.65)); // Angry
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.