根据数组值重新排列字符串 - Javascript

5

在Codewars上尝试解决此问题

我看到了其他文章,涉及随机洗牌/混淆字符串。

但是如何根据给定数组中的值混淆字符串?

例如:abcd 给定数组 [0, 3, 2, 1] 将变成 acdb 因为:

  • a 移动到索引0
  • b 移动到索引3
  • c 移动到索引2
  • d 移动到索引1

我的猜测是首先将字符串分割成一个数组。然后我们想要获取传递到scramble函数中的数组的索引值,并将该数组中索引值处的字符推入新数组中。最后连接数组:

function scramble(str, arr) {

  let newArray = str.split("");
  let finalArray = [];

  for (let i = 0; i < str.length; i++) {
    console.log(newArray);
    finalArray.push(newArray.splice(arr[i], 1));
  }
  return finalArray;
}

console.log(scramble("abcd", [0, 3, 1, 2]));

但这种逻辑的问题是.splice()每次都会从newArray中删除字符。
有没有另一种方法可以在不修改原始数组的情况下删除指定索引处的字符?
我认为slice也行不通。

你的问题不一致;你问如何从数组中删除某些内容,同时又不影响该数组。答案是“你不能”——这就是“删除”的定义。如果你只想获取特定索引处的字符,那就用 slice 方法... - Heretic Monkey
如果提供的数组长度与字符串长度不同,会出现什么情况?或者这种情况永远不会发生吗? - zfrisch
根据编码挑战,这种情况是不会发生的。 - HappyHands31
4个回答

3

您可以创建一个独立的数组来存储字母。

var str = "abcd";
var arr = [0, 3, 2, 1];
function scramble(s, a) {
    var ar = Array(a.length);
    a.forEach((e, i) => {
        ar[e] = s[i];
    });
    return ar.join('');
}
console.log(scramble(str, arr));


我不知道你可以创建一个指定长度的“空白”数组。就像其他答案一样,将字符串索引值分配给新数组的值更有效率。谢谢! - HappyHands31

2

最初的回答

使用 reduce 函数对数组进行迭代,当迭代时将字符串(s)中迭代器索引(i)的字符赋值给新数组(ra)中的值索引(v)。在完成 reduce 后,使用 join 将返回的数组(ra)转换回字符串。

let scramble = (s, a) => a.reduce((ra,v,i)=> (ra[v] = s[i], ra), []).join("");

Example:

let scramble = (s, a) => a.reduce((ra,v,i)=> (ra[v] = s[i], ra), []).join("");

console.log( scramble("abcd", [0,3,2,1]) );


澄清代码:

我意识到以上代码可能很难理解。让我为您提供相同的功能,但使用标准函数。请记住,这正是发生在上面代码中的事情,但如果您不习惯ES6的简洁性,则可能更容易理解:

最初的回答

function scramble(my_string, my_array) { 
   // create an array to return
   let returnable_array = [];

   // loop through the provided array. 
   // string index is the array key: 0,1,2,3
   // array_index is the value of the array keys: 0,3,2,1

   for(let [string_index, array_index] of my_array.entries()) {

   // we assign the character at string index 
   // to the value index inside the returnable array

    returnable_array[array_index] = my_string[string_index];
   } 

   // we turn the array into a string
   let returnable_string = returnable_array.join("");

   // we return the string
   return returnable_string
}

Example:

    function scramble(my_string, my_array) { 
       let returnable_array = [];
       for(let [string_index, array_index] of my_array.entries()) {
        returnable_array[array_index] = my_string[string_index];
       } 
       returnable_string = returnable_array.join("");
       return returnable_string
    }


console.log(scramble("abcd", [0,3,1,2]));


1

我认为最好的方法是将字符串放入一个新数组中:

    function scramble(str, arr) {
        //validate if the array has elements
        if (arr && arr.length) {
            //create a new array
            const strArr = []
            arr.forEach(index => {
                //push each character by index
                //As noted by Barmar you could either use
                //str.charAt(index) or str[index]
                //as both will return the character at the specified index
                strArr.push(str.charAt(index))
            })
            //return a new string
            return strArr.join('');
        }
    }

1
你也可以直接使用 str[i],不需要调用函数。 - Barmar
你是对的Barmar,字符串也像数组一样运作。 - Fernando Bravo Diaz

1
你可以循环输入字符串,使用 string.charAt(position) 获取当前位置的字符,并将其放入新数组中,该数组的位置由 positions 数组检索得到。

function scramble (str, arr) {
let newArray = [];
for (let i = 0; i < str.length; i++) {
    newArray[arr[i]]=str.charAt(i);
  }
  return newArray.join();
}

console.log(scramble("abcd", [0, 3, 1, 2]));


1
你也可以直接使用 str[i],不需要调用函数。 - Barmar
我没有意识到你可以像那样简单地将字符串值分配给newArray。这比尝试推入新数组要简单得多。在末尾加上return newArray.join(),这就可以工作了。 - HappyHands31
@Barmar - 很酷!好知道 - 不过如果我在字符串上使用数组访问,我不确定背后发生了什么。 - obscure
@HappyHands31 - 很高兴我能帮到你!=) - obscure
没有什么特别的事情发生。EcmaScript 5只是添加了这个等效功能。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#Character_access - Barmar
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接