I have a javascript which work correctly in Firefox, but it doesn't work in chrome!
The code is two array list that is supposed to sort a list of movies in alphabetical order.
One list from A to Z and one list with Z to A.
Any ideas what i have done wrong?
Thanks alot
var Movies = ["Pulp Fiction", "The Dark Knight", "Fight Club", " Terminator", "Matrix", "American History X", "Memento "];
function listMovies()
{
document.writeln("<b>Movies sort from A to B:</b>");
document.writeln(Movies.sort().join("<br>"));
document.writeln("<br><b>Movies sort from B to A:</b>");
document.writeln(Movies.sort(function(a, b){return b-a}).join("<br>"));
}
listMovies();
Two issues:
You have a space in front of Terminator which is throwing off the results.
Your "B to A" function is using the - operator on strings, which is not going to give you reliable results.
To solve #2, use a function that doesn't try to subtract strings:
document.writeln(Movies.sort(function(a, b){
return a == b ? 0 : (a < b ? 1 : -1)
}).join("<br>"));
Live Example
Side note: I'd avoid using document.writeln and similar.
First, you probably shouldn't be using document.writeLn. It's almost never necessary. Use DOM methods instead.
The problem, however, is that your code is trying to subtract one string from another in calculating the relative positions:
Movies.sort(function(a, b){return b-a})
This works fine with numbers (4 - 2 === 2) but not with strings ('Terminator' - 'American History' is NaN).
You need to compare with < and > instead, which makes your function a little more complex:
function listMovies()
{
document.writeLn("<b>Movies sort from A to B:</b>");
document.writeLn(Movies.sort().join("<br>"));
document.writeLn("<br><b>Movies sort from B to A:</b>");
document.writeLn(Movies.sort(function(a, b){
if (b === a) return 0;
if (b > a) return 1;
return -1;
}).join("<br>"));
}
The other oddity you have is that Terminator has a leading space, which causes it to go the beginning of the list alphabetically.
What about this DEMO ?
var Movies = ["Pulp Fiction", "The Dark Knight", "Fight Club", " Terminator", "Matrix", "American History X", "Memento "];
function listMovies(){
for(var i=0;i<Movies.length;i++){
Movies[i] = Movies[i].trim();
}
document.writeln("<b>Movies sort from A to B:</b>");
document.writeln(Movies.sort().join("<br>"));
document.writeln("<br><b>Movies sort from B to A:</b>");
document.writeln(Movies.sort(function(a, b){return b-a}).join("<br>"));
}
listMovies();
Related
I will receive an array of string-like below.
In each string, there may be three signs: $,%,* in the string
For example,
“I would $rather %be $happy, %if working in a chocolate factory”
“It is ok to play tennis”
“Tennis $is a good sport”
“AO is really *good sport”
However, there may be no signs in it, maybe only one sign in it.
There are only five cases in string,
1. no sign at all,
2. having $,% ;
3. having only $,
4 having only %,
5 having only *
If there is no sign, I don’t need to process it.
Otherwise, I need to process it and add an indicator to the left of the first sign that occurs in the sentence.
For example:
“I would ---dollorAndperSign—-$rather %be $happy, %if working in a chocolate factory”
“Tennis --dollorSign—-$is a good sport”
This is my idea code.
So, I need to decide if the string contains any sign. If there is no sign, I don’t need to process it.
texts.map((text) => {
if (text.includes("$") || text.includes("%") || text.includes("*")) {
//to get the index of signs
let indexOfdollar, indexOfper, indexOfStar;
indexOfdollar = text.indexOf("$");
indexOfper = text.indexOf("%");
indexOfStar = text.indexOf("*");
//return a completed process text
}
});
Question:
how do I know which index is the smallest one in order to locate the position of the first sign occurring in the text? Getting the smallest value may not be the correct approach coz there may be the case that I will get -1 from the above code?
I focussed only on the "get the smallest index" part of your question... Since you will be able to do what you want with it after.
You can have the indexOf() in an array, filter it to remove the -1 and then use Math.min() to get the smallest one.
Edited to output an object instead, which includes the first index and some booleans for the presence each char.
const texts = [
"I would $rather %be $happy, %if working in a chocolate factory",
"It is ok to play tennis",
"Tennis $is a good sport",
"AO is really *good sport"
]
const minIndexes = texts.map((text,i) => {
//to get the signs
const hasDollard = text.indexOf("$") >= 0
const hasPercent = text.indexOf("%") >= 0
const hasStar = text.indexOf("*") >= 0
//to get the first index
const indexes = [text.indexOf("$"), text.indexOf("%"), text.indexOf("*")].filter((index) => index >= 0)
if(!indexes.length){
return null
}
return {
index: Math.min( ...indexes),
hasDollard,
hasPercent,
hasStar
}
});
console.log(minIndexes)
const texts = [
"I would $rather %be $happy, %if working in a chocolate factory",
"It is ok to play tennis",
"Tennis $is a good sport",
"AO is really *good sport"
]
texts.forEach(text => {
let sighs = ["%","$","*"];
let chr = text.split('').find(t => sighs.find(s => s==t));
if (!chr)
return;
text = text.replace(chr, "---some text---" + chr);
console.log(text);
})
const data = ['I would $rather %be $happy, %if working in chocolate factory', 'It is ok to play tennis', 'Tennis $is a good sport', 'AO is really *good sport']
const replace = s => {
signs = { $: 'dollar', '%': 'per', '*': 'star' },
characters = Array.from(s, (c,i)=> '$%*'.includes(c)? c:'').join('')
headText = [...new Set(Array.from(characters))].map(c => signs[c]).join('|')
s.replace(/[\$\%\*]/, `--${text}--$&`);
}
const result = data.map(replace)
how would I sort this using .sort() function in javascript? I know I can add a comparison function here but I'm not sure how I would program this.
Before
1 024c
100 000c
143c
1 020c
10 000c
After
143c
1 020c
1 024c
10 000c
100 000c
If your input is an array then you can use a comparator function
(a,b) => a.replace(/[^\d.]/g, "") - b.replace(/[^\d.]/g, "")
this will remove c and space from the string to form number and compare. See the code below.
var data = ["1 024c",
"100 000c",
"143c",
"1 020c",
"10 000c"]
var sorted = data.sort( (a,b) => a.replace(/[^\d.]/g, "") - b.replace(/[^\d.]/g, ""));
console.log(sorted);
It seems like you want to sort it based on the numbers in them, while excluding spaces.
x.sort(
(eachObj, prevObj) =>
parseInt(eachObj.replace(" ","")) - parseInt(prevObj.replace(" ",""))
);
In ES6
I have been working on a Rubik’s Cube Timer website, and I need to make a scrambling algorithm. I’ll go over how the scrambling algorithm should work:
Each face has it’s own letter, it’s initial. for examble, if you want to move the front face, you would write “ F “. If you want to move the the right face, you would write “ R “, and so on. just note that the bottom face is D, as for down. So you have D U R L B F.
If there is nothing after that letter, you turn it clockwise. If there is an appostrophe “ ‘ “, you turn it counter-clockwise. If there is a 2, you turn it two times. Now the thing is that you cannot have 2 same letters next to oneanother, as they would cancel (For example “.. U U’ ...” would be the same as doing nothing. So far, I have this taken care of in my algorithm.
The problem comes when you have one letter, then it’s opposite, then again the first letter, ( For example “.. U D U’...” (would mean Up clockwise, Down clockwise, Up counterclokwise)).
I have no idea how to check for these and avoid them automatically. Here’s the code:
<div id=“Scramble”></div>
<script>
generateScramble();
function generateScramble() {
// Possible Letters
var array = new Array(" U", " D", " R", " L", " F", " B")
// Possible switches
var switches = ["", "\'", "2"];
var array2 = new Array(); // The Scramble.
var last = ''; // Last used letter
var random = 0;
for (var i = 0; i < 20; i++) {
// the following loop runs until the last one
// letter is another of the new one
do {
random = Math.floor(Math.random() * array.length);
} while (last == array[random])
// assigns the new one as the last one
last = array[random];
// the scramble item is the letter
// with (or without) a switch
var scrambleItem = array[random] + switches[parseInt(Math.random()*switches.length)];
array2.push(scrambleItem); // Get letters in random order in the array.
}
var scramble = "Scramble: ";
// Appends all scramble items to scramble variable
for(i=0; i<20; i++) {
scramble += array2[i];
}
document.getElementById("Scramble").innerHTML = scramble; // Display the scramble
}
</script>
For starters God's Number is 20 for Rubik;s cube so you got only 20 moves instead of 25. I assume you are not doing scrambling (as your title suggest) but instead generate solution command strings for genere&test solver type. There are too many sequences that cancel each other and to check for all of them would be most likely slower than try them out actually.
The problem is that even O(n^20) is huge and you need to lower the 20. That is done by LUT holding semi solved states. For example create table holding states for all combinations of 5 turn scrambling. Then use that as end condition turning your solver into O(n^15 + n^5) = O(n^15) ...
This question already has answers here:
How do you reverse a string in-place in JavaScript?
(57 answers)
Closed 7 years ago.
I'm going through tutorials to code (I'm fairly new at this), and this particular exercise is racking my brain. Here are the parameters:
Reverse the provided string.
You may need to turn the string into an array before you can reverse it. Your result must be a string.
and here is the code I'm given to start with:
function reverseString(str) {
return str;
}
reverseString('hello');
expect(reverseString('hello')).to.be.a('String');
expect(reverseString('hello')).to.equal('olleh');expected 'hello' to equal 'olleh'
expect(reverseString('Howdy')).to.equal('ydwoH');expected 'Howdy' to equal 'ydwoH'
expect(reverseString('Greetings from Earth')).to.equal('htraE morf sgniteerG');expected 'Greetings from Earth' to equal 'htraE morf sgniteerG'
Any suggestions out there on how to accomplish this?
** Edit: I figured out what my issue was. The particular IDE of the tutorial site made it confusing. Apparently I was meant to hit one of the objectives listed (not all of them in one script as I previously thought). This was accomplished by return str.split( '' ).reverse( ).join( '' );. The parameters for the split and join methods were a little confusing at first as well. Most online tutorials of this method use splitting words as an example, so I didn't realize going from
" " to ""
would change the process from reversing words to reversing letters.
Arrays have a method called reverse( ). The tutorial is hinting at using this.
To convert a string into an array of characters (in reality they're just single character strings), you can use the method split( ) with an empty string as the delimiter.
In order to convert the array back into a string, you can use the method join( ) again, with an empty string as the argument.
Using these concepts, you'll find a common solution to reversing a string.
function reverseString(str) {
return str.split( '' ).reverse( ).join( '' );
}
Pretty manual way to accomplish this
var j = 'abcdefgh';
var k = j.split('');
var reversedArr = []
for(var i = k.length; i >= 0; i--) {
reversedArr.push(k[i])
}
var reversedStr = reversedArr.join('')
console.log(reversedStr)
You can read more here: http://eddmann.com/posts/ten-ways-to-reverse-a-string-in-javascript/
function reverse(s) {
var o = '';
for (var i = s.length - 1; i >= 0; i--)
o += s[i];
return o;
}
A string is an array of characters, so you can use the reverse function on the array to reverse it and then return it:
function reverseString(str) {
return str.split('').reverse().join('');
}
var reversedStr = normalStr.split("").reverse().join("");
I am facing quite a challenge here. I am to sort certain Chinese "expressions" by pinyin.
The question:
How could I sort by pinyin in Firefox?
Is there a way to sort properly in IE 9 and 10? (They are also to be supported by the website)
Example:
财经传讯公司
财经顾问
房地产及按揭
According to a translator agency, this is what the sort order of the words should be. The translations are as follows:
Financial communication agencies
Financial consultancies
Real estate and mortgages
The pronanciations in latin alphabet:
cai jing chuan xun gong si
cai jing gu wen
fang di chan ji an jie
String.localeCompare:
MDN Docs
From what I understand I am to provide a 2nd argument to the String.localeCompare method that "tells" the method to sort by pinyin in BCP 47 format which should be zh-CN-u-co-pinyin.
So the full code should look like this:
var arr = [ "财经传讯公司", "财经顾问", "房地产及按揭"];
console.dir(arr.sort(function(a, b){
return a.localeCompare(b, [ "zh-CN-u-co-pinyin" ]);
}));
jsFiddle working example
I expected this to log to console the expressions in the order I entered them in the array but the output differs.
On FX 27, the order is: 3, 1, 2
In Chrome 33: 1, 2, 3
In IE 11: 1, 2, 3
Note:
Pinyin is the official phonetic system for transcribing the Mandarin
pronunciations of Chinese characters into the Latin alphabet.
This works on Chrome:
const arr = ["博","啊","吃","世","中","超"]
arr.sort((x,y)=>x.localeCompare(y, 'zh-CN'))
In general, people will use the following method for Chinese characters pinyin sort
var list=[' king ', 'a', 'li'];
list.Sort(function (a, b) {return a.localeCompare(b); });
localeCompare () : with local specific order to compare two strings.
This approach to pinyin sort is unreliable.
Second way: very dependent on Chinese operating system
Is very dependent on the browser kernel that is to say, if your site visitors are through the Chinese system, or the Internet explorer browser (Chrome), then he will probably unable to see the pinyin sort the result we expected.
Here I'll introduce my solution to this problem, hope to be able to derive somehow:
this method supports the Unicode character set x4e00 from 0 to 0 x9fa5 area a total of 20902 consecutive from China (including Taiwan), Japan, South Korea, Chinese characters, namely, CJK (Chinese Japanese Korean) characters.
var CompareStrings={.........}
getOrderedUnicode: function (char) {
var originalUnicode=char.charCodeAt ();
if (originalUnicode >=0 x4e00 && originalUnicode <=0 x9fa5) {
var index=this.Db.IndexOf (char);
if (index >1) {
return index + 0 x4e00;
}}
return originalUnicode;
},
compare: function (a, b) {
if (a==b) {return 0; }
//here can be rewritten according to the specific needs and the writing is the empty string at the bottom the if (a.length==0) {return 1; }
if (b.length==0) {return - 1; }
var count=a.length >B.length? B.length: a.length;
for (var i=0; i<count; i++) {
var au=this.GetOrderedUnicode (a [i]);
var bu=this.GetOrderedUnicode [i] (b);
if (au >bu) {
return 1;
} else if (au <bu) {
return - 1;
}}
return a.length >B.length? 1:1;
}}
//rewriting system native localeCompare
The prototype:
LocaleCompare = function (param) {
return CompareStrings.compare said (enclosing the toString (), param);
}
you can through the links below to download the complete code
A brief introduction of the principle of implementation:
According to pinyin sort good character (db) : there are multiple ways to achieve a goal, I am done with JavaScript + c# combination, use the script first put all the enumeration of Chinese characters, and then submitted to the c #good background sort, and output to the front desk, this is just the preparation, what all can.
Identify two characters who is bigger (getOrderedUnicode) : because when ordering, not only to deal with Chinese characters, and Chinese characters outside of the characters, so the comparator must be able to identify all of the characters, we here by judging whether a character is to discriminate Chinese characters: if it is Chinese characters, then the sort good word library search index, the index value plus the Unicode character set the location of the first Chinese characters, is after the "calibration" of the Unicode character set of the index value; If not Chinese characters, then return it directly on the index value of the Unicode character set.
Compare two strings (compare) : by comparing two each of the characters (within the effective range comparison, that is, the shorter the length of the string), if you find a greater than b, it returns 1, vice return 1.
Within the effective range after the comparison if haven't the tie, just see who is longer, such as a='123', b='1234', so long b to row in the back.
EDIT
You can also use JQuery plugin:
jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"chinese-string-asc" : function (s1, s2) {
return s1.localeCompare(s2);
},
"chinese-string-desc" : function (s1, s2) {
return s2.localeCompare(s1);
}
} );
See the original post.
According to MDN, locales and options arguments in localeCompare() have been added in Firefox 29. You should be able to sort by pinyin now.
Here is a solution:
<!--
pinyin_dict_notone.js and pinyinUtil.js is available in URL below:
https://github.com/sxei/pinyinjs
-->
<script src="pinyin_dict_notone.js"></script>
<script src="pinyinUtil.js"></script>
<script>
jQuery.extend(jQuery.fn.dataTableExt.oSort, {
"chinese-string-asc": function(s1, s2) {
s1 = pinyinUtil.getPinyin(s1);
s2 = pinyinUtil.getPinyin(s2);
return s1.localeCompare(s2);
},
"chinese-string-desc": function(s1, s2) {
s1 = pinyinUtil.getPinyin(s1);
s2 = pinyinUtil.getPinyin(s2);
return s2.localeCompare(s1);
}
});
jQuery(document).ready(function() {
jQuery('#mydatatable').dataTable({
"columnDefs": [
{ type: 'chinese-string', targets: 0 }
]
});
});
</script>