无法获取数组以正确显示嵌套 for 循环的结果
Unable to get array to display results of a nested for loop correctly
我正在尝试完成一个 codewars 练习,您只需 return 根据字符串中的数字按顺序排列的单词字符串。
示例:
order("is2 Thi1s T4est 3a") // should return "Thi1s is2 3a T4est"
order("4of Fo1r pe6ople g3ood th5e the2") // should return "Fo1r the2 g3ood 4of th5e pe6ople")
这是我目前的尝试:
function order(words) {
let wordsArr = words.split(' ')
let result = [];
for (let i = 0; i < wordsArr.length; i++) {
for (let j = 0; j < wordsArr[i].length; j++) {
if (typeof wordsArr[i][j] === 'number') {
result[wordsArr[i][j]] = wordsArr[i]
}
}
}
return result
}
然而,这只是 return 一个空数组。我的逻辑是,我循环遍历 wordsArr
中每个单词的每个字母,一旦 typeof
字母匹配 'number'
,然后我设置 results
数组索引 wordsArr[i][j]
等于wordsArr[i]
。但这并没有像我期望的那样工作,我很困惑为什么!
wordsArr[i][j]
是一个字符,不管它是否是数字,所以你需要检查它是否是一个数字,你可以用 /\d/
的正则表达式匹配来完成。如果是数字,则将单词添加到结果中:
function order(words) {
let wordsArr = words.split(' ')
let result = [];
for (let i = 0; i < wordsArr.length; i++) {
for (let j = 0; j < wordsArr[i].length; j++) {
if (wordsArr[i][j].match(/\d/)) {
result[wordsArr[i][j]] = wordsArr[i]
}
}
}
return result.join(' ')
}
console.log(order("is2 Thi1s T4est 3a")) // should return "Thi1s is2 3a T4est"
console.log(order("4of Fo1r pe6ople g3ood th5e the2")) // should return "Fo1r the2 g3ood 4of th5e pe6ople")
一个更有效的解决方案是使用正则表达式来定位每个单词中的数字字符,然后将剩余数字转换为实际数字。
const a = order("is2 Thi1s T4est 3a")
const b = order("4of Fo1r pe6ople g3ood th5e the2")
console.log(a, b)
function order(words) {
return words.split(' ')
.map(w => ({word:w, n:Number(/\d+/.exec(w)[0])}))
.sort((a, b) => a.n - b.n)
.map(o => o.word)
}
它所做的是在拆分字符串之后,将每个单词映射到一个包含该单词及其包含的数字的对象,并将其转换为实际数字。然后它根据该数字对映射数组进行排序,最后映射回返回的单词数组。
它假设每个单词确实都有一个数字,所以在正则表达式的 .exec
上没有检查 null
。
这是一种使用简单转换的方法。
const stripChars = word => word.replace(/[A-Za-z]+/g, '')
const xf = word => parseInt(stripChars(word), 10)
const order = words => words.split(' ').sort((a, b) => xf(a) - xf(b)).join(' ')
console.log(
order('is2 Thi1s T4est 3a'),
)
console.log(
order('4of Fo1r pe6ople g3ood th5e the2'),
)
看起来是使用 sort
的好案例:
function order(str){
const r = str.split(/\s+/);
r.sort((a,b)=>{
let m1 = a.match(/\d+/) || [a], m2 = b.match(/\d+/) || [b];
return m1[0]>m2[0];
});
return r;
}
console.log(order('is2 Thi1s T4est 3a'));
console.log(order('4of Fo1r pe6ople g3ood th5e the2'));
console.log(order('a zebra now just2 another1 test3 b'));
也许在一行中有其他解决方案:
- 拆分数组。
- 使用
sort(comparable)
重新排序元素。
- 将每个单词转换成一个数组
- 检查是否有数字。
- 比较
sort
里面的这些数字
- 加入单词(数组元素)
const order = str => str.split(" ").sort((a, b) => Array.from(a).find(e =>
e.match(/\d/)) > Array.from(b).find(e => e.match(/\d/)) ? 1 : -1).join(" ")
console.log(order("is2 Thi1s T4est 3a"))
console.log(order("4of Fo1r pe6ople g3ood th5e the2"))
我正在尝试完成一个 codewars 练习,您只需 return 根据字符串中的数字按顺序排列的单词字符串。
示例:
order("is2 Thi1s T4est 3a") // should return "Thi1s is2 3a T4est"
order("4of Fo1r pe6ople g3ood th5e the2") // should return "Fo1r the2 g3ood 4of th5e pe6ople")
这是我目前的尝试:
function order(words) {
let wordsArr = words.split(' ')
let result = [];
for (let i = 0; i < wordsArr.length; i++) {
for (let j = 0; j < wordsArr[i].length; j++) {
if (typeof wordsArr[i][j] === 'number') {
result[wordsArr[i][j]] = wordsArr[i]
}
}
}
return result
}
然而,这只是 return 一个空数组。我的逻辑是,我循环遍历 wordsArr
中每个单词的每个字母,一旦 typeof
字母匹配 'number'
,然后我设置 results
数组索引 wordsArr[i][j]
等于wordsArr[i]
。但这并没有像我期望的那样工作,我很困惑为什么!
wordsArr[i][j]
是一个字符,不管它是否是数字,所以你需要检查它是否是一个数字,你可以用 /\d/
的正则表达式匹配来完成。如果是数字,则将单词添加到结果中:
function order(words) {
let wordsArr = words.split(' ')
let result = [];
for (let i = 0; i < wordsArr.length; i++) {
for (let j = 0; j < wordsArr[i].length; j++) {
if (wordsArr[i][j].match(/\d/)) {
result[wordsArr[i][j]] = wordsArr[i]
}
}
}
return result.join(' ')
}
console.log(order("is2 Thi1s T4est 3a")) // should return "Thi1s is2 3a T4est"
console.log(order("4of Fo1r pe6ople g3ood th5e the2")) // should return "Fo1r the2 g3ood 4of th5e pe6ople")
一个更有效的解决方案是使用正则表达式来定位每个单词中的数字字符,然后将剩余数字转换为实际数字。
const a = order("is2 Thi1s T4est 3a")
const b = order("4of Fo1r pe6ople g3ood th5e the2")
console.log(a, b)
function order(words) {
return words.split(' ')
.map(w => ({word:w, n:Number(/\d+/.exec(w)[0])}))
.sort((a, b) => a.n - b.n)
.map(o => o.word)
}
它所做的是在拆分字符串之后,将每个单词映射到一个包含该单词及其包含的数字的对象,并将其转换为实际数字。然后它根据该数字对映射数组进行排序,最后映射回返回的单词数组。
它假设每个单词确实都有一个数字,所以在正则表达式的 .exec
上没有检查 null
。
这是一种使用简单转换的方法。
const stripChars = word => word.replace(/[A-Za-z]+/g, '')
const xf = word => parseInt(stripChars(word), 10)
const order = words => words.split(' ').sort((a, b) => xf(a) - xf(b)).join(' ')
console.log(
order('is2 Thi1s T4est 3a'),
)
console.log(
order('4of Fo1r pe6ople g3ood th5e the2'),
)
看起来是使用 sort
的好案例:
function order(str){
const r = str.split(/\s+/);
r.sort((a,b)=>{
let m1 = a.match(/\d+/) || [a], m2 = b.match(/\d+/) || [b];
return m1[0]>m2[0];
});
return r;
}
console.log(order('is2 Thi1s T4est 3a'));
console.log(order('4of Fo1r pe6ople g3ood th5e the2'));
console.log(order('a zebra now just2 another1 test3 b'));
也许在一行中有其他解决方案:
- 拆分数组。
- 使用
sort(comparable)
重新排序元素。 - 将每个单词转换成一个数组
- 检查是否有数字。
- 比较
sort
里面的这些数字
- 加入单词(数组元素)
const order = str => str.split(" ").sort((a, b) => Array.from(a).find(e =>
e.match(/\d/)) > Array.from(b).find(e => e.match(/\d/)) ? 1 : -1).join(" ")
console.log(order("is2 Thi1s T4est 3a"))
console.log(order("4of Fo1r pe6ople g3ood th5e the2"))