4

This is my first post so I hope im doing this correctly.

I am taking a coding class and we were asked to make a piece of code that will ask for the input of a phrase, and will return in the console that phrase with the capital letters moved to the front, but still in the same order. Then print to the console this reordered phrase. (We aren't allowed to use arrays) For example: Inputting "HeLLoTherE" would return "HLLTEeoher"

However the problem is im having issues understanding how to write this code. How can I make the code select these capital letters and move them to the front? using .toUpperCase()? How can i make that select the letter and move it in front of the rest? If someone could show me an example of how this is done and explain it a little i would greatly appreciate it :)

AlexSp3
  • 2,201
  • 2
  • 7
  • 24
  • 1
    `.toUpperCase()` won't do you any good; the characters of interest are already upper-case. You need to assemble a new string with two loops: the first to append the upper-case characters, and the second to append the lower-case characters. At the end, the new string will be your answer. – Pointy Apr 24 '22 at 12:59
  • I found some code that looks like this online: `var string='ACBacb'; alert(string.split('').sort(caseInsensitiveSort).join('')); function caseInsensitiveSort(a, b) { var ret = 0; a = a.toLowerCase();b = b.toLowerCase(); if(a > b) ret = 1; if(a < b) ret = -1; return ret; } ` Just it prints like this: "AaBbCc" instead of ABCabc, any way to change that? Im unsure of how to order parts of a string, like changing the order of these new letters – itsacode001 Apr 24 '22 at 13:06
  • Sorting is not guaranteed to leave the characters in their original order, and is also unnecessary. And, on top of that, `.split()` will give you an array, and your question says that you cannot use arrays. – Pointy Apr 24 '22 at 13:08
  • Ahhh i didnt know that .split() was for arrays, thanks! – itsacode001 Apr 24 '22 at 13:10
  • The real challenge here is coming up with a legit way of detecting an upper-case character. For a general solution across languages, it's not easy in JavaScript, and the regular expression solutions are probably beyond what the OP has available in the classroom materials involved. A simple Latin 1 solution is not hard however. – Pointy Apr 24 '22 at 13:18
  • We have just recently been introduced to strings (charAt, toUpperCase, and stuff like that too). Arrays is our next topic. :) – itsacode001 Apr 24 '22 at 13:21
  • 1
    Right, and I also guess that "upper-case" here does not mean "any representable character among all Unicode orthographies that would be considered 'upper-case' by a linguist". – Pointy Apr 24 '22 at 13:23

7 Answers7

2

Well, you are not able to use arrays, which makes it a little bit difficult, however you can still do sommething.

Although I'm using a for loop, I'm not actually using arrays. Since strings allows the [] operator, you can use an index to select each character of the string and check if it's lowercase or uppercase.

In addition, you said you need to mantain the order of uppercase letters, so you couldn't just do newStr = upper + newStr, because it would revert the original order. So, I used the string.prototype.substring() to insert the uppercase character where it should be.

const str = "HeLLoTherE";

const moveUpperToFront = (target) => {
  // Strings are immutable in js, so you cannot move one character
  // to the front without using a new string.
  let newStr = "";
  // Number of uppercase letters that appeared.
  // It's necessary because you need to mantain the original order
  let upperNumber = 0;
  // Iterate each character from beginning
  for (let i = 0; i < str.length; ++i) {
    // Is there an uppercase letter?
    if (str[i].charCodeAt() >= 65 && str[i].charCodeAt() <= 90) {
      newStr =
        newStr.substring(0, upperNumber) +
        str[i] +
        newStr.substring(upperNumber, newStr.length);

      ++upperNumber;
    }
    // No uppercase letter?
    else
      newStr += str[i];
  }
  return newStr;
};

console.log(moveUpperToFront(str));
AlexSp3
  • 2,201
  • 2
  • 7
  • 24
2

You might just start with a the most straight forward algorithm to get something working.

let value = "HeLLoTherE";
let result = "";

for (let char of value) {
  if (char >= "A" && char <= "Z") {
    result += char;
  }
}

for (let char of value) {
  if (char >= "a" && char <= "z") {
    result += char;
  }
}

console.log(result);

You could then consolidate the 2 loops by combining the conditions.

let value = "HeLLoTherE";
let upper = "";
let lower = "";

for (let char of value) {
  if (char >= "A" && char <= "Z") {
    upper += char;
  } else if (char >= "a" && char <= "z") {
    lower += char;
  }  
}

console.log(upper + lower);

Another way of solving this would be to use regex.

var value = "HeLLoTherE";
var upper = value.replace(/[^A-Z]*/g, "");
var lower = value.replace(/[^a-z]*/g, "");

console.log(upper + lower);
Brenden
  • 1,947
  • 1
  • 12
  • 10
  • Yes I think this is probably what the course instructor is expecting. – Pointy Apr 24 '22 at 13:24
  • Hi! Thanks a ton for the answer! And thanks for showing the multiple different ways as well. One question, what does `let char of value` do? Is it basically like "For every character in the value, do"? Also, for this part `if (char >= "A" && char <= "Z")`, does this basically just check if the character of the value defined earlier is between uppercase A-Z, then checks if its between lowercase a-z? – itsacode001 Apr 24 '22 at 13:34
  • 1
    @itsacode001 Yes exactly! – Brenden Apr 24 '22 at 13:41
  • Another feature is that if there are any characters in the input-string which are neither upper-case nor lower-case characters (say "HeLl0123WorLd"), the code in this answer will simply remove them (ie, the characters 0, 1, 2, 3 from the example input will not be found in the output). – jsN00b Apr 24 '22 at 14:32
1

This answer tries to achieve the desired objective without using "arrays". It does use back-ticks, but that can be replaced with a simple string-concatenation if required.

Code Snippet

// move upper-case letters while
// keeping relative order same
const capsWithOrder = str => {
  // initialize result variables
  let capsOnly = "", restAll = "";
  // iterate over the given string input
  for (let i = 0; i < str.length; i++) {
    // if character at index "i" is upper-case
    // then, concatenate character to "capsOnly"
    // else, concatenate to "restAll"
    if (str[i] === str[i].toUpperCase()) capsOnly += str[i];
    else restAll += str[i];
  };
  // after iterating over all characters in string-input
  // return capsOnly concatenated with restAll
  return `${capsOnly}${restAll}`;
};

console.log(capsWithOrder("HeLLoTherE"));

Explanation

Inline comments added in the snippet above.

jsN00b
  • 3,584
  • 2
  • 8
  • 21
1

Following a solution which uses a for...of loop to iterate the input. It splits the input into capital and lowercase literals and then merges back together:

const exampleLiteral = 'HeLLoTherE';

const isUppercase = (literal) => literal === literal.toUpperCase() && literal !== literal.toLowerCase();

const prefixCapitalLetters = (literal) => {
    let capitalLetters = '';
    let lowerLetters = '';
    for (let letter of literal) {
        if(isUppercase(letter)) {
            capitalLetters = capitalLetters.concat(letter);
            continue;
        }
        lowerLetters = lowerLetters.concat(letter);
    };
    return capitalLetters+lowerLetters;
}

console.log(prefixCapitalLetters(exampleLiteral));
alexanderdavide
  • 1,487
  • 3
  • 14
  • 22
1

This is really not a very hard problem:

function rearrange(str) {
  let result = "";
  for (let c of str)
    if (c >= 'A' && c <= 'Z')
      result += c;
  for (let c of str)
    if (c < 'A' || c > 'Z')
      result += c;
  return result;
}

console.log(rearrange("Hello World, It Is A Beautiful Morning!"));

Find the upper-case characters, and add them to a result string. Then go back and find the other characters, and add them at the end. By looping through without any sorting, just simple iteration from start to finish, the order is preserved (other than the upper-case stuff).

The truly hard part of this would be coming up with a way to detect "upper-case" letters across all of Unicode. Some languages (well, orthographies) don't have the concept at all. JavaScript has ways that are more and less convenient to deal with that, but I suspect for the classroom material the OP has available so far, given the nature of the original question, such regex trickery would probably be inappropriate for an answer.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • _way to detect "upper-case" letters across all of Unicode_ So true ! This question got me searching about it & [case in point](https://stackoverflow.com/q/30762886/13658816) --> [toLocaleUpperCase](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase). – jsN00b Apr 24 '22 at 13:32
  • Hi @jsN00b , does String.prototype.toLocaleUpperCase() convert to uppercase and also convert the string to a different language that would be defined in the parenthesis? I looked at the link and thats what it looked like but wanted to see if that's right – itsacode001 Apr 24 '22 at 13:36
  • 3
    @itsacode001 it *might*, but constructing logic out of that would be a little difficult. The issue is with characters like spaces, which are not affected by `.toUpperCase()` or `.toLowerCase()`. So the logic really should concentrate on characters that are "letters", and doing that requires some regular expression work. I suspect that for your JavaScript programming class, something simple like my suggestion or the other similar answer is what the instructor is looking for. – Pointy Apr 24 '22 at 13:42
0

Something like this

const string1 = 'HeLLoTherE'

const transform = string => {

  const lower = string.split('').filter(c => c.charCodeAt() > 'a'.charCodeAt())
  const upper = string.split('').filter(c => c.charCodeAt() < 'Z'.charCodeAt())
  return [...upper, ...lower].join('')
}

console.log(transform(string1))
R4ncid
  • 6,944
  • 1
  • 4
  • 18
-1

I think that must be work.

const sort = [
    'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''),
    'abcdefghijklmnopqrstuvwxyz'.split('')
]

function listByValue(string) {
    string = [...string];
    let ret = [];
    for (let i in sort) 
        ret = [...ret,...string.filter(e=>sort[i].includes(e))];
    return ret.join('')
}
Wraith
  • 1
  • 1