Shuffle a Questions array and an Answers multidimensional array the same - javascript

Alright, so the thing is;
Now I made this website for myself to study japanese more easily, by making a list of japanese words and its definition. I put the japanese words in lesson1.txt and the answers in lesson1answers.txt in the same order. I read them out in php and put them in arrays in javascript.
Now the problem is is that these arrays have the same order every time I start the site, which is quite annoying for me as I keep resembling the spot to the answer, and I dont even read the japanese word (Damn our human brains!). So I figured the best way to solve this is by randomizing the elements of both the arrays, but they both have to be randomized in the same pattern because else the question doesnt correspond correctly to the answer anymore.
One of the arrays I have is multidimensional. The array first holds elements that represent the lines I read out of a .txt file. The line has multiple characters in it, consequently the second element of the array represents each character (Dont ask me why I did this, it had to do with me not being able to read out japanese characters in php and put them in js directly). The other array is just the array I keep the answers in.
So I have AnswersArray(); and JapaneseCharactersArray();
I've been stuck on this problem for a whole day now, someone please help or give a hint..

You should merge them into one array of objects:
// assuming AnswersArray.length == JapaneseCharactersArray.length
var array = [];
for (var i=0; i<AnswersArray.length; i++)
array[i] = {
answer: AnswersArray[i],
japanese: JapaneseCharactersArray[i]
};
Now you have only one array, each item containing all information on a single word. You can easily shuffle it now.
Instead of AnswersArray[x] you then would use array[x].answer further down in your code.
Of course, you could just adapt your fisherYates function to shuffle two or more arrays in the same way:
function fisherYates(first/*, ... arrays */) {
var i = first.length,
argl = arguments.length;
if (i == 0) return false;
while (--i) {
var r = Math.floor(Math.random() * (i + 1));
for (var j=0; j<argl; j++) {
var tempi = arguments[j][i];
var tempj = arguments[j][r];
arguments[j][i] = tempj;
arguments[j][r] = tempi;
}
}
}
// usage:
> fisherYates(AnswersArray, JapaneseCharactersArray);

Although the best way is probably to just create them as a single array, another way is to create a new array, of the same length as the others, where each item in the array is a number: 1, 2, 3 ... n. But instead of having the numbers in order, use Math.random() to randomize their order.
Then loop through that new array as such:
for(i=0; i<AnswersArray.length; i++) {
AnswersArray[RandomArray[i]]; // whatever
}
Another way is to just swap the entire row when you randomize the array.

Related

JavaScript Undefined when alert(array.length) is called [duplicate]

This question already has answers here:
Length of a JavaScript object
(43 answers)
Closed 2 years ago.
Lately I have been trying to create a webpage with a search feature. My way of implementing this, while not the fastest or most elegant, should work in theory. All it does is split the search term into a list, the delimiter being a space, and then splits the keywords (in dictionary format, with the value being a download link, and with the key being the "keywords" I was referring to) and finally, it has an outer loop looping through the keys (being split each iteration into a list), and an inner loop looping through the words input through the input field. If a word in the search field matches one keyword of the key words list, then that key from the dictionary gets a score of +1.
This should sort the keys into order of best result to worst, and then the code can continue on to process all this information and display links to the downloadable files (the point of the webpage is to supply downloads to old software [of which I have collected over the years] etc.). However, when I run the program, whenever the alert(ranking.length) function is called, all I get is undefined in the output window.
Here is the code. (The search() function is called whenever the search button is pressed):
var kw_href = {
"windows":["windows3.1.7z"],
"ms dos 6.22":["ms-dos 6.22.7z"]
}
function search(){
var element = document.getElementById("search_area");
var search_term = element.value.toLowerCase();
var s_tags = search_term.split(" ");
var keys = Object.keys(kw_href);
ranking = {
"windows":0,
"ms dos 6.22":0
};
for (i = 0; i < keys.length; i++){
keywords_arr = keys[i].split(" ");
for (x = 0; x < s_tags.length; x++){
if (keywords_arr.includes(s_tags[x])){
ranking[keys[i]] = ranking[keys[i]] + 1;
}
}
}
// now we have a results list with the best results. Lets sort them into order.
alert(ranking.length);
}
Edit
alert(ranking.length) line is for debugging purposes only, and I was not specifically trying to find the length.
ranking is a generic object, not an array, so it won't have a computed length property.
If you want to count the number of properties in it, convert it to an array with Object.keys(ranking).
ranking should be array of object like ranking =[{"windows":0,"ms dos 6.22":0},{"windows":1,"ms dos 6.22":10}]
Then length ranking.length will work

Filled Array with unique Elements - How can i copy it so i get every order possible?

This is my first question here, I think the answer will be a small piece of Code.
Lets say i have a filled array at any lenght with unique elements:
let a = [A,B,C]
My question is,
How can I process the array, so that I have a list or x arrays , that show every possible order for these elements of the array above
like:
A,B,C
A,C,B
B,A,C
B,C,A
C,B,A
C,A,B
I dont really have an idea and tried to look in the web so far.
Thanks for the answers!
The recursive idea is:
function order(list, ans){
let size = list.length;
if(size == 0){
console.log(ans);
return;
}
for(var i = 0; i < size; i++){
let first = list.shift();
order(list, ans + `${first},`);
list.push(first);
}
}
Basically, for each element, you set it as a first and recursively do the same thing with the rest of the list.

Javascript - delete array items by value LIKE [duplicate]

This question already has answers here:
remove all items in array that start with a particular string
(5 answers)
Closed 7 years ago.
I have this simple array
var array = ['x.89999', 'y.sisisis', 'x.585858'];
I want to remove all the items in the array starting by 'x.' so to return this array:
['y.sisisis']
How can i do this without having to loop or iterate all the entire array? (i know it's probably not possible so don't mind if not possible)
Is there some builtin / native code i can use?
Thanks
you may use array.filter()
var newArray = array.filter(function(item){
return item.indexOf('x.') !== 1;
});
there is no way to do this job without looping through the whole array.
The only case – array is sorted alphabetically. But sorting demands looping through too
Assuming that the items to be removed will always precede the other items alphabetically (ie x is before y), you can sort your array and then break the loop as soon as the non-x value has been found:
function filter(arr) {
arr.sort();
for (var i = 0, l = arr.length; i < l; i++) {
if (arr[i][0] !== 'x') {
break;
}
}
return arr.slice(i);
}
filter(arr); // logs: "Iterated to 5 of array length 9"
DEMO
Of course, as JazzCat mentions, this is no good if you only have one y value and it's right at the end of the array - you're still going to have to iterate over the whole array.
Alternate option is to use regular expression, something like this. Fix your regex according to your requirement.
var array = ['x.89999', 'y.sisisis', 'x.585858'];
var filtArr = array.filter(function(x){
return x.match("^[x].+$");
});
console.log(filtArr);
One different answer not using explicit iteration or Array.prototype.filter:
var array = ['x.89999', 'y.sisisis', 'x.585858'];
array = array.join("#").replace(/(#?x\.\w*)/g,"").replace(/^#/,"").split("#");
//["y.sisisis"]
Of course you will need to take care of the separator character.
The good point is that it works on old browsers (ie8) while Array.prototype.filter does not.

Matching Array to JavaScript Matrix

I’m wondering how to solve a matching/lookup problem and I “think” a multi-dimensional array is the solution. In short, I want to match a list of comma separated SKUs stored as a cookie value against a finite list of SKUs with matching product names and print out the matched product names onto the page. I’m not sure if this is the best way to do this, but with what I have so far I’m not clear how to properly breakup the comma separated strings from the cookie (right now it’s trying to match the entire cookie value), match them to the matrix (17 total rows) and then print out the Product Name.
<script>
var staticList = [
[“1234”, “Chocolate Ice Cream”],
[“1235”, “Peanut Butter Cookie”],
[“6G2Y”, “Raspberry Jell-O”],
[“YY23”, “Vanilla Wafers”]
];
var cookieSkus = [‘1235,YY23’]; // comma separated value from cookie
jQuery(function () {
for (var i = 0; i < staticList.length; i++) {
if (cookieSkus.indexOf(staticList [i][0]) > -1) {
jQuery('#pdisplay).append(staticList [i] [1] + '<br />');
}
}
});
</script>
<p id=”pdisplay”></p>
In this example, the paragraph "pdisplay" would contain:
Peanut Butter Cookie
Vanilla Wafers
Is there a way to correct what I have above or is there a better method of accomplishing what I’m trying to do?
First, you might want to focus on the Cookie SKUs rather than the staticList. The reason for this is that the cookie may have a variable number, and may be as small as 0 elements. (After all, we don't need to list the items if there are no items).
This may be accomplished simply by converting the string to an array and then checking if the SKU is in the staticList. Unfortunately, since you are using a multidimensional array, this would require going through the staticList for each cookie sku. Using just this suggestion, here is a basic example and fiddle:
Rewrite: Accounting for the fact that staticList is an Array of Arrays
jQuery(function() {
var skus = cookieSkus[0].split(',');
for (var i = 0; i < skus.length; i++) {
for (var j = 0; j < staticList.length; j++) {
if (staticList[j][0] == skus[i]) {
jQuery('#pdisplay').append(staticList[j][2] + '<br/>');
break; // Will end inner if the item is found... Saves a lot of extra time.
}
}
}
});
Edit 2: Using an Object (A possibly better approach)
According to the comments, you must support IE8. In this case, you might consider an Object instead of a multi-dimensional array. The reasons for this are as follows:
An object is actually an associative array (with a few perks).
You can directly check for property existence without having any nested arrays.
Object property access is typically faster than looping through an array
You can access object properties nearly exactly like accessing an array's elements.
When using an Object, the original version of my code may be used without modification. This is because the object's structure is simpler. Here is a fiddle for you: option 2
var staticList = {
"1234": "Chocolate Ice Cream",
"1235": "Peanut Butter Cookie",
"6G2Y": "Raspberry Jell-O",
"YY23": "Vanilla Wafers"
};
jQuery(function() {
var skus = cookieSkus[0].split(',');
for (var i = 0; i < skus.length; i++) {
if (staticList[skus[i]])
jQuery('#pdisplay').append(staticList[skus[i]] + '<br/>');
}
});
Responding to your comment:
The reason that the output matches what is desired is because unlike an array which has numerical indices, the object's indices are the actual skus. So, there is no staticList[0] if staticList is an object. Instead (in the context of the staticList object), 1234 = "Chocolate Ice Cream". So, an object definition basically goes as follows:
var objectName = {
index1: value1,
index2: value2,
...,
...
}
The index may be any primitive value (integer or string). The value may be any valid javascript value including a function or an inner object. Now, to get the value at a specific index, you may do either:
objectName.index1 (no quotes)
OR:
objectName["index1"] (quotes needed if the index is a string)
The result of either of those will be:
value1
It's as simple as that.
I would try something like this:
var cookieSkus = cookieSkus[0].split(',');
staticList.filter(function(cell){
return cookieSkus.some(function(val){return cell[0] === val; });
}).map(function(cell){
jQuery('#pdisplay).append(cell[1] + '<br />');
});
Disclaimer: provided based on the sample code provided above along with recent comments

Cannot get unique values in card array

I am new to programming and javascript and i have a question ive been struggling with for a bit now. Im trying to build a card game and have a card object which returns a card representation of the format (card #,suit eg. 5,Hearts). I deal a card at the start of the program and validate that the card dealt is unique (ie not been used already). I have the following structure:
var usedCards= [];
function dealCards() {
for (i = 0; i < 3; i++)
{
var card = createUniqueCard();
usedCards.push(card.cardRepresentation);
}
}
function createUniqueCard() {
do {
var newCard = new Card();
}
while (usedCards.indexOf(newCard.cardRepresentation) != -1);
return newCard;
}
This still returns me duplicate cards in my usedCards array. Can anyone point out my logic error?
Thanks
If newCard.cardRepresentation is an object then .indexOf() will never find a match because two object references are considered equal only if they refer to the same instance - you keep creating new instances with new Card().
If you can have newCard.cardRepresentation as a string it should work. Or if you write your own function to replace .indexOf(), where your function knows how to compare two .cardRepresentation objects...
I think a better solution is to begin by generating all possible cards, putting them in an array, and then your deal function could randomly select from that array.

Categories