CodingBat altPairs问题:如何简化现有JavaScript实现方案?
altPairs Function for CodingBat Hey there! Let's tackle simplifying your altPairs function for that CodingBat challenge. First, let's recap the problem to make sure we're on the same page:
Given a string, return a new string made of characters at indexes 0,1,4,5,8,9... For example,
altPairs('kitten')returns"kien".
Test cases:
altPairs('kitten') → kienaltPairs('Chocolate') → CholealtPairs('CodingHorror') → Congrr
Your Current Approach
Your code works perfectly, but it relies on multiple array splits and loops which adds unnecessary complexity. Here's your original code for reference:
function altPairs(str) { // 将字符串转换为数组 let newArr = str.split("") // 创建两个空数组,用于存储原数组中指定索引的字符 // myArrOne 将存储索引0、4、8……的字符 let myArrOne = []; // myArrTwo 将存储索引1、5、9……的字符 let myArrTwo = []; // 遍历原数组两次,将元素推入myArrOne和myArrTwo for (let i = 0; i < newArr.length; i += 4) { myArrOne.push(newArr[i]) } for (let i = 1; i < newArr.length; i += 4) { myArrTwo.push(newArr[i]) } // 创建新数组,遍历myArrOne和myArrTwo,将元素推入myArrThree let myArrThree =[]; for (let i = 0; i <= myArrOne.length && i <= myArrTwo.length; i++){ myArrThree.push(myArrOne[i], myArrTwo[i]) } // 将myArrThree通过join方法转换为新字符串 let myString = myArrThree.join('') return myString }
Cleaner, More Concise Solutions
Let's look at a few streamlined approaches that cut down on boilerplate while keeping the logic clear:
Solution 1: Single Loop with Chunk Logic
This approach iterates through the string in chunks of 4, grabbing the first two characters of each chunk directly. No array splitting required!
function altPairs(str) { let result = ''; // Jump 4 positions each time to target 0-1, 4-5, 8-9, etc. for (let i = 0; i < str.length; i += 4) { // Add the current character result += str[i]; // Add the next character only if it exists (avoids out-of-bounds errors) if (i + 1 < str.length) { result += str[i + 1]; } } return result; }
How it works: We loop starting at index 0, incrementing by 4 each iteration. For each starting index i, we append str[i] and (if it's within bounds) str[i+1] to our result string. This builds the desired output in one pass, with minimal overhead.
Solution 2: Functional Style with reduce
If you prefer a declarative, functional approach, we can use Array.from and reduce to filter and build the result:
function altPairs(str) { return Array.from(str).reduce((acc, char, idx) => { // Keep characters where index mod 4 is 0 or 1 (matches 0,1,4,5,8,9...) if (idx % 4 === 0 || idx % 4 === 1) { acc += char; } return acc; }, ''); }
How it works: Convert the string to an array, then use reduce to iterate over each character. We check if the character's index modulo 4 equals 0 or 1—if yes, we add it to our accumulator string. This reads like plain English: "keep characters at positions that are 0 or 1 in every 4-character block".
Solution 3: Regular Expression (Ultra Compact)
For the shortest possible implementation, a regex can match and capture exactly the characters we want:
function altPairs(str) { // Match 4-character segments, capture first two; handle leftover characters at the end return str.replace(/(.{2}).{2}|(.{1,2})$/g, '$1$2'); }
How it works: The regex (.{2}).{2} targets every 4-character sequence, capturing the first two characters. The |(.{1,2})$ handles the end of the string if there are 1 or 2 characters left. We replace each match with the captured groups, effectively discarding the unwanted characters in each 4-block.
All Solutions Pass the Test Cases
Every one of these approaches will correctly return:
altPairs('kitten') → "kien"altPairs('Chocolate') → "Chole"altPairs('CodingHorror') → "Congrr"
内容的提问来源于stack exchange,提问作者Roman

