将字符串数组转换为对象数组,其中每个字符串本身都有一个分隔符
Convert array of strings into array of objects where each string itself has a separator
我有一个字符串数组:
["aa-q1-true", "bb-q1-false", "cc-q1-true", "aa-q2-true", "xx-q2-false", "yy-q2-true", "mm-q3-true", "mn-q3-false", "qr-q3-false"]
每个字符串都有意义。例如,如果我们考虑第一个字符串,即 "aa-q1-true"
这里第一部分 - aa
是测验答案,中间部分 - q1
是问题和 true
,最后部分是答案状态。状态可以是 true
或 false
。此规则适用于数组中的每个字符串。
现在我想把它转换成如下的对象数组 -
[
0: [{
quizAns: [{aa: true}, {bb: false}, {cc: true}]
quizQuestion: q1
}]
1: [{
quizAns: [{aa: true}, {xx: false}, {yy: true}]
quizQuestion: q2
}]
2: [{
quizAns: [{mm: true}, {mn: false}, {qr: false}]
quizQuestion: q3
}]
]
我无法独自理解这样做的逻辑。如果你能给我一些想法或解决方案,那将非常有帮助。非常感谢您的宝贵时间。
你会想把每一项拆分成-
,然后你得到第一个和最后一个项目得到你的答案对象,中间得到它属于哪个问题,然后你就迭代构造解决方案:
let ans = ["aa-q1-true", "bb-q1-false", "cc-q1-true", "aa-q2-true", "xx-q2-false", "yy-q2-true", "mm-q3-true", "mn-q3-false", "qr-q3-false"].map((s) => s.split('-')).reduce((carry, current) => {
let existingIndex = carry.findIndex((item) => item.quizQuestion === current[1]);
if (existingIndex === -1) {
carry.push({quizAns: [], quizQuestion: current[1]});
existingIndex = carry.length - 1;
}
carry[existingIndex].quizAns.push({[current[0]]: current[2]});
return carry;
}, []);
console.log(ans);
只是另一种方法。与其他答案相比,对数组的循环更少。
let questions = { };
let ans = ["aa-q1-true", "bb-q1-false", "cc-q1-true", "aa-q2-true", "xx-q2-false", "yy-q2-true", "mm-q3-true", "mn-q3-false", "qr-q3-false"]
.reduce((acc, curr) => {
let elements = curr.split("-");
let obj = {};
obj[elements[0]] = elements[2];
if (questions[elements[1]]) {
questions[elements[1]].push(obj);
} else {
questions[elements[1]]= [obj];
}
}, {})
let result = [];
for (let prop in questions) {
result.push({ "quizAns": questions[prop], "quizQuestion": prop });
}
console.log(result);
只是另一种代码更少的方法
const resultMap = array.reduce((acc, item) => {
// current data
const [answer, quizQuestion, status] = item.split("-");
// previous answers
const previousAnswers = acc[quizQuestion] ? acc[quizQuestion].quizAns : [];
// new answers
const newAnswers = [...previousAnswers, { [answer]: status }];
return { ...acc, [quizQuestion]: { quizQuestion, quizAns: newAnswers } };
}, {});
const result = Object.values(resultMap)
console.log(result)
我不是 array.reduce
语法原因的可读性因素的忠实粉丝。
即使输入以杂乱无章的方式出现,此循环也能正常工作。
const a = ["aa-q1-true", "bb-q1-false", "cc-q1-true", "aa-q2-true", "xx-q2-false", "yy-q2-true", "mm-q3-true", "mn-q3-false", "qr-q3-false"];let results = [];
const retObj = (que, ans) => {
const obj = {};
obj[`${que}`] = ans;
return obj;
};
for (let i in a){
let currEleArr = a[i].split("-");
let tarInd = parseInt(currEleArr[1].split("")[1]) - 1;
let que = currEleArr[0];
let ans= currEleArr[2];
if (!results[tarInd])
results[tarInd] = [{quizAns: []}];
if(!results[tarInd][0].quizQuestion)
results[tarInd][0]["quizQuestion"] = `q${tarInd + 1}`;
results[tarInd][0].quizAns.push(retObj(que, ans));
}
console.log(results);
我有一个字符串数组:
["aa-q1-true", "bb-q1-false", "cc-q1-true", "aa-q2-true", "xx-q2-false", "yy-q2-true", "mm-q3-true", "mn-q3-false", "qr-q3-false"]
每个字符串都有意义。例如,如果我们考虑第一个字符串,即 "aa-q1-true"
这里第一部分 - aa
是测验答案,中间部分 - q1
是问题和 true
,最后部分是答案状态。状态可以是 true
或 false
。此规则适用于数组中的每个字符串。
现在我想把它转换成如下的对象数组 -
[
0: [{
quizAns: [{aa: true}, {bb: false}, {cc: true}]
quizQuestion: q1
}]
1: [{
quizAns: [{aa: true}, {xx: false}, {yy: true}]
quizQuestion: q2
}]
2: [{
quizAns: [{mm: true}, {mn: false}, {qr: false}]
quizQuestion: q3
}]
]
我无法独自理解这样做的逻辑。如果你能给我一些想法或解决方案,那将非常有帮助。非常感谢您的宝贵时间。
你会想把每一项拆分成-
,然后你得到第一个和最后一个项目得到你的答案对象,中间得到它属于哪个问题,然后你就迭代构造解决方案:
let ans = ["aa-q1-true", "bb-q1-false", "cc-q1-true", "aa-q2-true", "xx-q2-false", "yy-q2-true", "mm-q3-true", "mn-q3-false", "qr-q3-false"].map((s) => s.split('-')).reduce((carry, current) => {
let existingIndex = carry.findIndex((item) => item.quizQuestion === current[1]);
if (existingIndex === -1) {
carry.push({quizAns: [], quizQuestion: current[1]});
existingIndex = carry.length - 1;
}
carry[existingIndex].quizAns.push({[current[0]]: current[2]});
return carry;
}, []);
console.log(ans);
只是另一种方法。与其他答案相比,对数组的循环更少。
let questions = { };
let ans = ["aa-q1-true", "bb-q1-false", "cc-q1-true", "aa-q2-true", "xx-q2-false", "yy-q2-true", "mm-q3-true", "mn-q3-false", "qr-q3-false"]
.reduce((acc, curr) => {
let elements = curr.split("-");
let obj = {};
obj[elements[0]] = elements[2];
if (questions[elements[1]]) {
questions[elements[1]].push(obj);
} else {
questions[elements[1]]= [obj];
}
}, {})
let result = [];
for (let prop in questions) {
result.push({ "quizAns": questions[prop], "quizQuestion": prop });
}
console.log(result);
只是另一种代码更少的方法
const resultMap = array.reduce((acc, item) => {
// current data
const [answer, quizQuestion, status] = item.split("-");
// previous answers
const previousAnswers = acc[quizQuestion] ? acc[quizQuestion].quizAns : [];
// new answers
const newAnswers = [...previousAnswers, { [answer]: status }];
return { ...acc, [quizQuestion]: { quizQuestion, quizAns: newAnswers } };
}, {});
const result = Object.values(resultMap)
console.log(result)
我不是 array.reduce
语法原因的可读性因素的忠实粉丝。
即使输入以杂乱无章的方式出现,此循环也能正常工作。
const a = ["aa-q1-true", "bb-q1-false", "cc-q1-true", "aa-q2-true", "xx-q2-false", "yy-q2-true", "mm-q3-true", "mn-q3-false", "qr-q3-false"];let results = [];
const retObj = (que, ans) => {
const obj = {};
obj[`${que}`] = ans;
return obj;
};
for (let i in a){
let currEleArr = a[i].split("-");
let tarInd = parseInt(currEleArr[1].split("")[1]) - 1;
let que = currEleArr[0];
let ans= currEleArr[2];
if (!results[tarInd])
results[tarInd] = [{quizAns: []}];
if(!results[tarInd][0].quizQuestion)
results[tarInd][0]["quizQuestion"] = `q${tarInd + 1}`;
results[tarInd][0].quizAns.push(retObj(que, ans));
}
console.log(results);