如何从字符串中获取奇数和偶数位置字符?

时间:2019-03-24 20:32:32

标签: javascript string character

我正在尝试找出如何从Javascript字符串中删除第二个字符(从第一个字符开始)。 例如,字符串“这是一个测试!”应该成为“ hsi etTi sats”! 我也想将每个删除的字符保存到另一个数组中。

我尝试使用replace方法和splice方法,但无法使其正常工作。主要是因为replace只替换第一个字符。

<script>

var random = 1;


function prepareTable() {
var str = "",
    header = "",
    graphImg;


header = '\uFEFF<h2 style="text-align:center;">google</h2>';

str = '<table border="1">'
    +'<tr><td style="text-align:center" colspan="6">Yahoo</td></tr>'
  +'<tr><td style="font-weight:bold" colspan="6">(2017.03.20)</td></tr>'
    +'<thead>'
    +'    <tr style="background-color:#788496; color: #ffffff">'
    +'      <th scope="col" rowspan="2">'
    +'        <div>Yahoo</div>'
    +'      </th>'
    +'      <th scope="col">'
    +'        <div class="tar">Yahoo(2017-01)</div>'
    +'      </th>'
    +'      <th scope="col" colspan="2">'
    +'        <div class="tar">Yahoo(2016-12)</div>'
    +'      </th>'
    +'      <th scope="col" colspan="2">'
    +'        <div class="tar">Yahoo(2016-12)</div>'
    +'      </th>'
    +'    </tr>'
    +'    <tr style="background-color:#788496; color: #ffffff">'
    +'      <th height="40" align="right">'
    +'        <div>Yahoo</div>'
    +'      </th>'
    +'      <th align="right">'
    +'        <div>Yahoo</div>'
    +'      </th>'
    +'      <th align="right">'
    +'        <div>Yahoo</div>'
    +'      </th>'
    +'      <th align="right">'
    +'        <div>Yahoo</div>'
    +'      </th>'
    +'      <th align="right">'
    +'        <div>Yahoo</div>'
    +'      </th>'
    +'    </tr>'
    +'</thead>'
    +'  <tbody>'

+'    <tr style="text-align: right">'
+'      <td style="padding:0 20px 0 0">'
+'        <div>NAME</div>'
+'      </td>'
+'      <td style="width: 150px;">'
+'        <div>5</div>'
+'      </td>'
+'      <td style="width: 150px;">'
+'        <div>5</div>'
+'      </td>'
+'      <td style="width: 150px;">'
+'        <div>5</div>'
+'      </td>'
+'      <td style="width: 150px;">'
+'        <div>5</div>'
+'      </td>'
+'      <td style="width: 150px;">'
+'        <div>5</div>'
+'      </td>'
+'    </tr>';
+'  </tbody>'
+'</table>';

    return header + str;
 }


function doExcel1 () {
var blob,
    template = prepareTable();

blob = new Blob([template], {
    type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"
});

saveAs(blob, "test.xls");
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>
<a href="javascript:" class="btn_style1 excel" onclick="doExcel1()"><span>Excel</span></a>

9 个答案:

答案 0 :(得分:2)

使用正则表达式和.replace可能会更容易:在单独的捕获组中捕获两个字符,将第一个字符添加到字符串中,然后替换为第二个字符。然后,将需要的输出的前一半放在一个字符串中,将第二个字符串放在另一个字符串中:将它们连接在一起并返回:

function encrypt(text) {
  let removedText = '';
  const replacedText1 = text.replace(/(.)(.)?/g, (_, firstChar, secondChar) => {
    // in case the match was at the end of the string,
    // and the string has an odd number of characters:
    if (!secondChar) secondChar = '';
    // remove the firstChar from the string, while adding it to removedText:
    removedText += firstChar;
    return secondChar;
  });
  return replacedText1 + removedText;
}
console.log(encrypt('This is a test!'));

答案 1 :(得分:2)

您可以reduce字符串中的字符,并使用%运算符将它们分组为单独的数组。使用destructuring来将2D数组返回给单独的变量

let str = "This is a test!";

const [even, odd] = [...str].reduce((r,char,i) => (r[i%2].push(char), r), [[],[]])

console.log(odd.join(''))
console.log(even.join(''))

使用for循环:

let str = "This is a test!",
    odd = [],
    even = [];

for (var i = 0; i < str.length; i++) {
  i % 2 === 0
    ? even.push(str[i]) 
    : odd.push(str[i])
}

console.log(odd.join(''))
console.log(even.join(''))

答案 2 :(得分:2)

您可以获取一个数组并进行拼接,然后将第二个项目推到数组的末尾。

function encrypt(string) {
    var array = [...string],
        i = 0,
        l = array.length >> 1;
    
    while (i <= l) array.push(array.splice(i++, 1)[0]);
    
    return array.join('');
}

console.log(encrypt("This is a test!"));

答案 3 :(得分:1)

function encrypt(text) {
  text = text.split("");
  var removed = []
  var encrypted = text.filter((letter, index) => {
    if(index % 2 == 0){
      removed.push(letter)
      return false;
    }
    return true
  }).join("")
  return {
      full: encrypted + removed.join(""),
      encrypted: encrypted,
      removed: removed
  }
}

console.log(encrypt("This is a test!"))

拼接不起作用,因为如果从for loop索引中的数组中删除一个元素,则删除另一个元素时很可能会出错。

答案 4 :(得分:1)

使用.reduce()非常简单,可以创建您想要的两个数组。

function encrypt(text) {
  return text.split("")
             .reduce(({odd, even}, c, i) => 
                i % 2 ? {odd: [...odd, c], even} : {odd, even: [...even, c]}
             , {odd: [], even: []})
}

console.log(encrypt("This is a test!"));

如果需要,可以使用.join("")将它们转换为字符串。

答案 5 :(得分:1)

我认为您在正确的轨道上。您错过的替换是使用字符串或RegExp。

  

replace()方法返回一个新字符串,该字符串具有部分或全部匹配的模式,并由替换项替换。模式可以是字符串或RegExp,而替换项可以是字符串或每个匹配项要调用的函数。如果pattern是字符串,则只会替换第一个匹配项。

来源:String.prototype.replace()

  

如果要替换值(而不是正则表达式),则仅替换该值的第一个实例。要替换所有出现的指定值,请使用全局(g)修饰符

来源:JavaScript String replace() Method

所以我的建议是继续使用replace并将正确的RegExp传递给该函数,我想您可以从此示例中弄清楚-这样就消除了char't'的第二次出现:

let count = 0;
let testString = 'test test test test';

console.log('original', testString);

// global modifier in RegExp
let result = testString.replace(/t/g, function (match) {
  count++;
  return (count % 2 === 0) ? '' : match;
});

console.log('removed', result);

答案 6 :(得分:1)

像这样吗?

var text = "This is a test!"
var result = ""
var rest = ""
for(var i = 0; i < text.length; i++){
        if( (i%2) != 0 ){
          result += text[i]
	} else{
	  rest += text[i]
        }
}
console.log(result+rest)

答案 7 :(得分:1)

也许可以拆分,过滤和合并:

const remaining = myString.split('').filter((char, i) => i % 2 !== 0).join('');
const deleted = myString.split('').filter((char, i) => i % 2 === 0).join('');

答案 8 :(得分:1)

我不知道您对性能有多重视,但是使用正则表达式不是很有效。 对相当长的字符串进行的简单测试表明,使用过滤器功能的速度平均快了约3倍,这在处理非常长的字符串或许多很多短裤的字符串时会产生很大的不同。

function test(func, n){
	var text = "";
	for(var i = 0; i < n; ++i){
		text += "a";
    }	
	var start = new Date().getTime();
	func(text);
	var end = new Date().getTime();
  var time =  (end-start) / 1000.0;
	console.log(func.name, " took ", time, " seconds")
  return time;
}

function encryptREGEX(text) {
  let removedText = '';
  const replacedText1 = text.replace(/(.)(.)?/g, (_, firstChar, secondChar) => {
    // in case the match was at the end of the string,
    // and the string has an odd number of characters:
    if (!secondChar) secondChar = '';
    // remove the firstChar from the string, while adding it to removedText:
    removedText += firstChar;
    return secondChar;
  });
  return replacedText1 + removedText;
}

function encrypt(text) {
  text = text.split("");
  var removed = "";
  var encrypted = text.filter((letter, index) => {
    if(index % 2 == 0){
      removed += letter;
      return false;
    }
    return true
  }).join("")
  return encrypted + removed
}

var timeREGEX = test(encryptREGEX, 10000000);
var timeFilter = test(encrypt, 10000000);

console.log("Using filter is faster ", timeREGEX/timeFilter, " times")

filter vs regex - performance test result

实际上,使用数组存储删除的字母然后将它们连接起来比使用字符串并将其串联起来要有效得多。
我在过滤器解决方案中将数组更改为字符串,以使其与正则表达式解决方案相同,因此它们的可比性更高。