根据数组查找索引增加映射的值



我有一个数组:

const arr1 = [
"Strongly positive",
"Positive",
"Neutral",
"Negative",
"Strongly negative"
];

和响应对象:

const responses = [
{ values: { QID16: 3 } },
{ values: { QID16: ["1", "2", "3"] } },
{ values: { QID16: 1 } }
];

目标是创建一个返回映射的函数。映射的键是arr1的元素,如果它们的index + 1出现在responses对象中,则值是这些元素的计数。

例如,responses[0].values.QID16是3,它是中性的。(中性点有指数2(

问题是当响应中的值是类似于responses[1]中的数组时

我创建了以下功能:

function getCounts(mainId, choices, responses) {
let choicesCounts = new Map();
choices.forEach((choice, i) => {
choicesCounts.set(choice, 0);
const id = i + 1;
responses.forEach((response) => {
if (response.values[mainId] && response.values[mainId] === id) {
choicesCounts.set(choice, choicesCounts.get(choice) + 1);
}
if (
response.values[mainId] &&
Array.isArray(response.values[mainId]) &&
response.values[mainId].includes(id.toString())
) {
// this is the part where I need help
response.values[mainId].forEach((n) => {
choicesCounts.set(
choices.at(parseInt(n, 10) - 1),
choicesCounts.get(choices.at(parseInt(n, 10) - 1)) + 1
);
});
}
});
});
return choicesCounts;
}

它会被这样称呼:

console.log(getCounts("QID16", arr1, responses));

期望输出:

// desired output is a map not an object
const desiredOutput = {
"Strongly positive": 2, // number 1 appears twice in responses
Positive: 1, // number 2 appers once in responses
Neutral: 2,
Negative: 0,
"Strongly negative": 0
};

它在值是数字的情况下有效,但在值是数组的情况下无效。

这个函数有什么问题?有什么让它更简单的建议吗?

我认为你的问题在于你如何解决这个问题。

目前,对于arr1中的每个可能值,您都要在responses数组上迭代一次。当您在responses条目中遇到值的数组时,您检查它是否包含您当前"的值;寻找";,然后递增所做的所有选择。由于这将被循环多次,您也会将所有的循环次数增加几次,从而得到错误的计数。

如果不给你改变这一点的确切代码,只需以这种方式重组你的功能应该已经有助于获得一个更清洁的解决方案:

  • 更改处理顺序。与其在responses中搜索单个值;预处理";步骤,创建一个映射,表示在responses值中遇到的每个唯一键的计数
  • 结果几乎就是您想要的,只是键还没有映射到arr1的值。这样做的优点是,与responses数组相比,只需要一次迭代,就可以消除对某些值进行多次计数的问题
  • 如果你选择这种方法是因为CCD_ 11值可能包含你不感兴趣的值;跳过";这些,可以在预处理阶段通过在将当前检查的值写入结果映射之前检查其是否包含在arr1数组中来复制这种行为

这是否涵盖了您看到的问题,或者您是否遇到了其他实际错误?

OP应该考虑选择一种将整个任务分解为更小任务的方法。

  1. 从评级数组(字面上命名评级的数组(创建一个基于评级值(响应项的values附带的值(的映射,用于查找评级关键字(评级名称是要实现的评级计数映射的关键字(。

    const ratingValuesToKeys = new Map([
    "Strongly positive",
    "Positive",
    "Neutral",
    "Negative",
    "Strongly negative",
    ].map((key, idx) => [idx + 1, key]));
    console.log(Object.fromEntries([...ratingValuesToKeys]));

  2. 同样,从相同的评级阵列创建一个基于评级名称的映射,用于计算/汇总相关评级值的出现次数。

    const ratingCounts = new Map([
    "Strongly positive",
    "Positive",
    "Neutral",
    "Negative",
    "Strongly negative",
    ].map(key => [key, 0]));
    console.log(Object.fromEntries([...ratingCounts]));

  3. 对所有特定于密钥的评级值进行分类和收集,因为它们以不同的类型出现,如数字和/或字符串值以及数组。

    const ratingValues = [
    { values: { QID16: 3 } },
    { values: { QID16: ["1", "2", "3"] } },
    { values: { QID16: 1 } },
    ]
    .reduce((result, { values }) => {
    if (values.hasOwnProperty('QID16')) {
    const rating = values['QID16'];
    if (Array.isArray(rating)) {
    result
    .push(
    ...rating
    .map(value =>
    parseInt(value, 10)
    )
    );
    } else {
    result
    .push(parseInt(rating, 10));
    }
    }
    return result;
    }, []);
    console.log({ ratingValues });

  4. 根据所有净化的密钥特定的评级值,通过增加相关评级密钥的计数值来更新每个评级的出现。

最终的组合实现和示例代码可能看起来类似于。。。

const ratings = [
"Strongly positive",
"Positive",
"Neutral",
"Negative",
"Strongly negative",
];
const responses = [
{ values: { QID16: 3 } },
{ values: { QID16: ["1", "2", "3"] } },
{ values: { QID16: 1 } },
];
function getRatingCounts(responseValueKey, ratings, responses) {
// create a rating-value based map for looking up rating-keys.
const ratingValuesToKeys = new Map(
ratings
.map((key, idx) => [idx + 1, key])
);
// create a rating-key based map for counting/summing up ratings.
const ratingCounts = new Map(
ratings
.map(key => [key, 0])
);
// sanitize and collect all key specific rating-values
// for they are occurring as different types ... like
// number and/or string values as well as arrays.
const ratingValues = responses
.reduce((result, { values }) => {
if (values.hasOwnProperty(responseValueKey)) {
const rating = values[responseValueKey];
if (Array.isArray(rating)) {
result
.push(
...rating
.map(value =>
parseInt(value, 10)
)
);
} else {
result
.push(parseInt(rating, 10));
}
}
return result;
}, []);
// based on all sanitized key specific rating-values
// do update each rating's occurrence by incrementing
// the related rating-key's count-value.
ratingValues
.forEach(value => {
const ratingKey = ratingValuesToKeys.get(value);
const ratingCount = ratingCounts.get(ratingKey);
ratingCounts.set(ratingKey, ratingCount + 1);
});
return ratingCounts;
}
const ratingCounts = getRatingCounts('QID16', ratings, responses);
console.log({
ratingCounts,
'counts as entry list': [...ratingCounts],
'counts as object': Object.fromEntries([...ratingCounts]),
});
.as-console-wrapper { min-height: 100%!important; top: 0; }

相关内容

  • 没有找到相关文章

最新更新