【问题标题】:How to return a string based on correspondent values summed from an array of strings如何根据从字符串数组中求和的对应值返回字符串
【发布时间】:2020-01-24 00:30:46
【问题描述】:

正如主题所述,最好的方法是什么,以便在传递一组情绪/值时,根据 javascript 中的数字映射显示最接近的值?

假设“高兴”与“快乐”是一回事,而“沮丧”与“悲伤”是一回事。如果我添加更多情绪/状态(即愤怒),我尝试过的代码似乎非常冗长并且变得臃肿。除了情绪数组之外,任何新函数、数据结构和变量都可以更改/引入。

例如,我可以得到一个情绪列表:

let emotions = ['Happy','Happy','Sad','Glad','Angry']; 

现在我想根据这 5 种情绪返回一个反映“最接近”情绪的字符串。

举个更好的例子,假设每种情绪对应的值是:

愤怒 = 1,快乐 = 2,悲伤 = 3

我正在尝试类似:

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';

基于此情绪列表,我的预期结果是:
2(*Happy*) + 2(*Happy*) + 3(*Sad*) + 2(*Happy|Glad*) + 1(*Angry*) = 10
然后除以 5(情绪数组长度),得到 2。
所以应该以字符串形式返回的结果是 "Happy"

假设我添加了第四种情感/感觉......我会添加越来越多的这些条件,并且在检查数字范围的逻辑中变得更加复杂。

我正在查看整个情绪列表,并试图提出代表整个列表的整体情绪。

最好的方法是什么让代码看起来干净并且我可以支持更多的状态而不会让代码行变得太长?

【问题讨论】:

  • Math.round()?
  • @CalvinNunes 这可能是其中的一部分,但就我而言,我想要它,以便 1.5 意味着“快乐或悲伤”(中间立场),而不仅仅是默认向上取整。跨度>
  • 我觉得这个问题在codereview.stackexchange.com 上可能会有更好的归宿——你可以查看他们的主题规则
  • 是否要使用数组索引来获取字符串?你可以去掉小数点(如果不是整数),然后得到emotions[x] + ' or ' + emotions[x + 1]
  • 我认为这里有些混乱。用户传递的是情绪数组(字符串)还是浮点值数组?

标签: javascript arrays


【解决方案1】:

这样的事情怎么样:

有两个对象常量:
emotionsValues:在这里你为你想要的每一种情绪赋予一个价值,就像给每一种情绪一样。
emotionsRank:这是每个值的最终结果,根据平均值,您将从这里得到结果。

现在:

  1. 通过参数接收情绪数组。

  2. reduce 它基于每个映射情绪的值(使用emotionsValues)。

  3. 获取平均值

  4. 看看底值 + ceil 值除以 2 是否等于数字本身(这意味着它正好是一半),所以使用“情绪或情绪”。

  5. 或者,如果不是一半,则四舍五入到最近的并得到正确的情绪。不要忘记检查平均值是否低于最后排名的 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))

【讨论】:

  • 这是所有情绪的平均值吗?就像如果那里有压倒性数量的 Angry's... 这会解释吗?看看这个,它似乎只考虑了最小/最大,而不是每种情绪的数量/数量。我正在查看整个情绪列表,并试图提出一个代表整个列表的整体情绪。
  • 我认为理解你的目标以及情绪数组来自哪里有点混乱......但是不,它只是基于平均数,而不是基于数组,现在你说,我终于明白你的目标了……我现在时间不多,但如果可以的话,我会编辑并尝试回答你真正需要的内容
  • 你能发布你的问题,所有情绪的价值,(1=快乐,2=悲伤,...)?而且,emotions 数组是否被参数接收?你不能使用代码的第一部分,检查numbaverage,然后得到这个平均值并传递给我的getEmotion 函数,它不会导致你想要的目标吗?
  • 1-愤怒,2-快乐,3-悲伤。可以通过参数接收。是的,你可以这样做。
  • @Rolando 我认为我的编辑符合您的需要,请查看
【解决方案2】:
  • 您可以创建函数 emo to value 及其倒数:value to EmotionS:
  • 然后将数组中找到的每个情绪映射到它的值
  • 做标准数学题
  • 并通过互惠函数回归情绪

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

【讨论】:

    【解决方案3】:

    此函数显式检查“中间”情况以及超出范围的值(因为它基于索引):

    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];
    
    }
    

    输出:

    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
    

    【讨论】:

      【解决方案4】:

      您可以创建一组索引并通过索引过滤来获取值。

      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));

      【讨论】:

        猜你喜欢
        • 2021-12-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-23
        • 1970-01-01
        • 2018-06-29
        • 1970-01-01
        相关资源
        最近更新 更多