Related
I have two arrays villanStrength = [112,243,512,343,90,478] and playerStrength = [5,789,234,400,452,150] of same length, I am comparing each value of array playerStrength with villanStrength and forming up an another array which will store the either 0 or 1 (false or true) based on comparison, but the output array I am getting is not desirable. Please help me...
my code:
process.stdin.resume();
process.stdin.setEncoding('ascii');
var userInput = //providing this externally from the file
1
6
112 243 512 343 90 478
5 789 234 400 452 150;
var testCases = "";
var numberOfPlayers = "";
var villanStrength = [];
var playerStrength = [];
process.stdin.on('data', (data) => {
userInput = data;
// console.log("user input = " + userInput);
let res = userInput.split("\n");
testCases = res[0];
// for (i=1; i<=testCases; i++) {
numberOfPlayers = res[1];
// console.log("cases = " + testCases);
// console.log("number of players = " + numberOfPlayers);
villanStrength = res[2].split(" ");
playerStrength = res[3].split(" ");
console.log("villan Strength = " + villanStrength);
console.log("player Strength = " + playerStrength);
let isSmall = false;
let comparisonResult = [];
for (let j=0; j<villanStrength.length; j++) {
for (let k=0; k<playerStrength.length; k++) {
if (playerStrength[j] < villanStrength[k]) {
comparisonResult[k] = 1; //true = 1, false = 0
} else {
comparisonResult[k] = 0;
}
}
console.log("comparison result for " + j +":" + comparisonResult);
if(comparisonResult.find((findOne) => {return findOne = 1;} )) {
isSmall = true;
console.log("LOSE");
break;
}
}
if (isSmall === false) {
console.log("Win");
}
// }
});
The output array is comparisonResult[] and the values inside comparisonResult I am getting is as below:
villan Strength = 112,243,512,343,90,478
player Strength = 5,789,234,400,452,150
comparison result for 0: 0,0,1,0,1,0 //this should be 1,1,1,1,1,1
comparison result for 1: 0,0,0,0,1,0
comparison result for 2: 0,1,1,1,1,1
comparison result for 3: 0,0,1,0,1,1
comparison result for 4: 0,0,1,0,1,1
comparison result for 5: 0,1,1,1,1,1
in the above result it is expected that the 'comparison result for 0' should be [1,1,1,1,1,1] but it is [0,0,1,0,1,0].
There are a couple problems with this code.
When you compare values in your arrays, you are comparing strings, not numbers. The values you get from stdin are text values, not numeric values. So, for example '5' > '100'. I presume this is the major source of your issue. If you want to do numeric comparisons, you need to convert the strings to numbers.
You are assuming that you get ALL your data on the first data event. While that may usually be true, it is not guaranteed and you should not rely on it when programming. You have to collect data in one or more data events until you have a full chunk of data you can process.
If you add these two log statements that show the actual contents of the array (not the .toString() conversion of the array):
console.log("villan strength: ", villanStrength);
console.log("player strength: ", playerStrength);
You will see this output:
villan strength: [ '112', '243', '512', '343', '90', '478\r' ]
player strength: [ '5', '789', '234', '400', '452', '150;\r' ]
Note, these are strings and when coming from my text file, there's a trailing \r too.
If you change this:
villanStrength = res[2].split(" ");
playerStrength = res[3].split(" ");
to this:
villanStrength = res[2].split(" ").map(item => parseInt(item.trim(), 10));
playerStrength = res[3].split(" ").map(item => parseInt(item.trim(), 10));
Then, it will trim off the newline and convert them to numbers and your comparisons will make sense. This is why the code you posted originally in your question did not generate the wrong output because you hacked in an array of numbers (for purposes of the original question), but your original code was ending up with an array of strings.
Based on your requirement, the playerStrength loop needs to be the outer loop and comparisonResult should be an array of arrays
villanStrength = [112,243,512,343,90,478]
playerStrength = [5,789,234,400,452,150]
// ...
let comparisonResult = []; //output array
for (let j=0; j< playerStrength.length; j++) {
comparisonResult[j] = [];
for (let k=0; k<villanStrength.length; k++) {
if (playerStrength[j] < villanStrength[k]) {
comparisonResult[j].push(1); //true = 1, false = 0
} else {
comparisonResult[j].push(0);
}
}
console.log("comparison result for player " + j +":" + comparisonResult[j]);
}
If I understand the question right you need to compare each value from array1 to array2 and generate a new array that show diffrent...
All you need is just one loop that can take both values and push result of comparison to another array
function compare() {
const villanStrength = [112, 243, 512, 343, 90, 478];
const playerStrength = [5, 789, 234, 400, 452, 150];
const result = [];
for (let i = 0; i < villanStrength.length; i++) {
const vVal = villanStrength[i];
const pVal = playerStrength[i];
if (pVal < vVal) {
result.push(1);
continue;
}
result.push(0);
}
console.log(result);
}
My suggestion for is to separate codes to smaller funtions so you can focus on each section
my question is actually similar to: Extracting the most duplicate value from an array in JavaScript (with jQuery)
I Found this but it always return one value only which is 200.
var arr = [100,100,200,200,200,300,300,300,400,400,400];
var counts = {}, max = 0, res;
for (var v in arr) {
counts[arr[v]] = (counts[arr[v]] || 0) + 1;
if (counts[arr[v]] > max) {
max = counts[arr[v]];
res = arr[v];
}
}
console.log(res + " occurs " + counts[res] + " times");
pls help me to return values not just one...
The result is should like this:
200,300,400
.
pls help thank you!
You have to iterate your counts to find the max occurred result.
var arr = [100,100,200,200,200,300,300,300,400,400,400];
var counts = {}, max = 0, res;
for (var v in arr) {
counts[arr[v]] = (counts[arr[v]] || 0) + 1;
if (counts[arr[v]] > max) {
max = counts[arr[v]];
res = arr[v];
}
}
var results = [];
for (var k in counts){
if (counts[k] == max){
//console.log(k + " occurs " + counts[k] + " times");
results.push(k);
}
}
console.log(results);
Create a Object iterating the arry containing the indexes of most repeated values, like below
var arr = [100,100,200,200,200,300,300,300,400,400,400];
valObj = {}, max_length = 0, rep_arr = [];
arr.forEach(function(el,i){
if(valObj.hasOwnProperty(el)){
valObj[el] += 1;
max_length = (valObj[el] > max_length) ? valObj[el] : max_length
}
else{
valObj[el] = 1;
}
});
Object.keys(valObj).forEach(function(val){
(valObj[val] >= max_length) && (rep_arr.push(val))
});
console.log(rep_arr);
After the object is created with key as array value and value as array indexes of that value, you can play/parse that. Hope this helps.
Iterating an array using for..in is not a good idea. Check this link for more information.
Hopefully below snippet will be useful
var arr = [100, 100, 200, 200, 200, 300, 300, 300, 400, 400, 400];
//Use a reduce fuction to create an object where 100,200,300
// will be keys and its value will the number of times it has
//repeated
var m = arr.reduce(function(i, v) {
if (i[v] === undefined) {
i[v] = 1
} else {
i[v] = i[v] + 1;
}
return i;
}, {});
// Now get the maximum value from that object,
//getMaxRepeated will be 3 in this case
var getMaxRepeated = Math.max(...Object.values(m));
//An array to hold elements which are repeated 'getMaxRepeated' times
var duplicateItems = [];
// now iterate that object and push the keys which are repeated
//getMaxRepeated times
for (var keys in m) {
if (m[keys] === getMaxRepeated) {
duplicateItems.push(keys)
}
}
console.log(duplicateItems)
The following would do the trick assuming that all items in arr are numbers:
//added some numbers assuming numbers are not sorted
var arr = [300,400,200,100,100,200,200,200,300,300,300,400,400,400];
var obj = arr.reduce(//reduce arr to object of: {"100":2,"200":4,"300":4,"400":4}
(o,key)=>{//key is 100,200, ... o is {"100":numberOfOccurrences,"200":numberOf...}
o[key] = (o[key])?o[key]+1:1;
return o;
},
{}
);
// obj is now: {"100":2,"200":4,"300":4,"400":4}
//create an array of [{key:100,occurs:2},{key:200,occurs:4}...
var sorted = Object.keys(obj).map(
key=>({key:parseInt(key),occurs:obj[key]})
)//sort the [{key:100,occurs:2},... by highest occurrences then lowest key
.sort(
(a,b)=>
(b.occurs-a.occurs===0)
? a.key - b.key
: b.occurs - a.occurs
);
console.log(
sorted.filter(//only the highest occurrences
item=>item.occurs===sorted[0].occurs
).map(//only the number; not the occurrences
item=>item.key
)
);
Try as following ==>
function getDuplicate( arr ){
let obj = {}, dup = [];
for(let i = 0, l = arr.length; i < l; i++){
let val = arr[i];
if( obj[val] /**[hasOwnProperty]*/ ) {
/**[is exists]*/
if(dup.find(a => a == val) ) continue;
/**[put Unique One]*/
dup.push(val);
continue;
};
/**[hold for further use]*/
obj[val] = true;
}
return dup;
};
Use ==>
getDuplicate([100,100,200,200,200,300,300,300,400,400,400]);
Try the following:
var candles = [100,100,200,200,200,300,300,300,400,400,400];
let tempArray = {}
for (let index = 0; index <= (candles.length - 1); index++) {
let valueToCompare = candles[index];
if (tempArray[valueToCompare]) {
tempArray[valueToCompare] = tempArray[valueToCompare] + 1;
} else {
tempArray[valueToCompare] = 1;
}
}
let highestValue;
Object.values(tempArray).forEach(item => {
if (highestValue === undefined) highestValue = item;
if (highestValue < item) highestValue = item;
});
console.log(highestValue);
I'm new student in here,sorry for asking simple question and I'm trying to solve a problem to count a same letter.
Input:"aabbcde"
cause a = 2, b= 2, c= 1 , d =1 , e = 1
Output:"2a2b1c1d1e" or a2b2c1d1e1
and here's my code unfinished, I stucked
function repeatL(str) {
var word = str.split("").sort();
var temp = 0;
var i =1;
while(i< word.length){
if(word[i] === word[i +1]) {
//return temp to array of a += 1 ?
};
}
}
repeatL("abbbdd"); //output should be a1b3d2
also what if the input is not string but an array:
Input:[a,ab,bc,d,e]
is that even possible to solved?
You could use a variable for the result string, start with a count variable with 1 and iterate with a check of the former and actual letter. Then either count or move the count to the result set with the last letter. Reset counter to one, because the actual letter count is one.
At the end, finish the result with the last count and the letter, because one letter is not processed with the count (remember, you start with index 1, and you look always to the letter before of the actual index).
function repeatL(str) {
var word = str.split("").sort(),
count = 1,
i = 1,
result = '';
while (i < word.length) {
if (word[i - 1] === word[i]) {
count++;
} else {
result += count + word[i - 1];
count = 1;
}
i++;
}
result += count + word[i - 1];
return result;
}
console.log(repeatL("aabbcde"));
console.log(repeatL(['a', 'ab', 'bc', 'd', 'e'].join(''))); // with array after joining
You can simply use reduce() to build array and then join() to get string.
var input = "aabbcde";
var result = input.split('').reduce(function(r, e) {
var i = r.indexOf(e);
(i != -1) ? r[i - 1] ++: r.push(1, e)
return r;
}, []).join('')
console.log(result)
I'd go with an object and add each character as a key. If the key exists increment the value, else add a new key and with value 1
function repeatL(str) {
var count = {};
var arr = str.split("");
str = "";
for(var i=0;i<arr.length;i++){
if(count[arr[i]]){
count[arr[i]] = count[arr[i]]+1;
}
else {
count[arr[i]] = 1;
}
}
for(var key in count){
str+= key+count[key];
}
return str;
}
Following example also works with arrays:
function getFrequency(string) {
var freq = {};
for (var i=0; i<string.length;i++) {
var character = string[i];
if (freq[character]) {
freq[character]++;
} else {
freq[character] = 1;
}
}
return freq;
};
function repeatL(str) {
var freq = getFrequency(str);
result = '';
for (var k in freq) {
if (freq.hasOwnProperty(k)) {
result += freq[k] + k;
}
}
return result;
};
console.log(repeatL('abbbdd'));
console.log(repeatL('aabbcdeaaabbeedd'));
console.log(repeatL(['a', 'a', 'b', 'a', 'c']));
Sorry if this has already been asked but I did search "javascript sort index linked array" and found nothing satisfactory.
I've got an array of names, and another index linked array which records the frequency at which the names appear in a passage, and I want to sort both arrays not alphabetically but according to the name frequencies - say, most frequent to least frequent. I've got the following bit of code which does the job adequately, but I'm thinking that it looks like a hack. Surely there's a more decorous way to solve what must be a pretty common sorting problem.
I start with an array of names[] say, 6 Johns, 2 Annes, 9 Toms, 12 Andrews, 3 Kristens, 1 Archie, and 14 Peters - already sorted alphabetically and counted into frequencies, and the routine below results in an array of indexes to the names and frequency arrays which allows me to display the names and frequencies in order from highest to lowest.
var names = ["Andrew", "Anne", "Archie", "John", "Kristen", "Peter", "Tom"];
var frequency = [12, 2, 1, 6, 3, 14, 9];
var holder = [], secondpart = [], numindex = [];
var i;
for (i = 0; i < frequency.length; i++) {
if (frequency[i] < 10) {
holder[i] = "0" + frequency[i] + "!" + i; // add leading zeros as required
}
if (frequency[i] > 9) {
holder[i] = frequency[i] + "!" + i; // no leading zeros required
}
}
holder.sort();
holder.reverse();
for (i = 0; i < holder.length; i++) {
secondpart[i] = holder[i].substring(holder[i].indexOf("!") + 1, holder[i].length);
numindex[i] = parseInt(secondpart[i]);
}
I can now list both arrays according to the name frequencies.
var txt = "";
var useindex;
for (i = 0; i < numindex.length; i++) {
useindex = numindex[i];
txt = txt + names[useindex] + " - " + frequency[useindex] + "<br>";
}
Has anyone else had this problem and how did you solve it.
try this:
var names = ["Adam", "Peter", "Mahu", "Lala"];
var frequencies = [6,2,9,1];
var tupples=[];
for(let i = 0; i<names.length; i++)
{
tupples[i] = {
frequency : frequencies[i],
name : names[i]
};
}
//ascending
//tupples.sort(function(a,b){return a.frequency-b.frequency;});
//descending
tupples.sort(function(a,b){return b.frequency-a.frequency;});
for(let i=0; i<tupples.length; i++)
{
console.debug(tupples[i].name, tupples[i].frequency);
}
Basically you could use the indices and sort them by getting the the frequency for the given index.
var names = ['Andrew', 'Anne', 'Archie', 'John', 'Kristen', 'Peter', 'Tom'],
frequency = [12, 2, 1, 6, 3, 14, 9],
indices = names.map(function(_, i) { return i; });
indices.sort(function(a, b) {
return frequency[b] - frequency[a];
});
document.write('<pre>' + JSON.stringify(indices, 0, 4) + '</pre>');
document.write(indices.map(function(a) { return names[a]; }).join('<br>'));
So I have an array. The array has string values inside that can change each time:
var array = ['1','2','3','4','5'];
or sometimes:
var array = ['1','4','3','4','4'];
or even:
var array = ['1','3','3','4','4'];
How would I go about iterating through this array, figuring out which value is present the most and then displaying it. Also, how would I go about making it even smarter to understand that sometimes there is a tie between two values, as is the case in the last array above, and then displaying info notifying me that values "3" and "4" are tied... Or if there is no value that occurs more than once, thus displaying all values. Thoughts?
function findMostFrequent(array) {
// {
// "valueInTheArray": numberOfOccurances,
// ...
// }
var data = {};
// for each value in the array increment the number of
// occurences for that value. the or clause defaults it to 0.
$.each(array, function(i, val) {
data[val] = data[val]++ || 1;
});
var answer = null;
// for each value if the occurances is higher then to the counter.
// then set that as the counter.
$.each(data, function(key, val) {
if (val > data[answer]) answer = key;
}
return answer;
}
You need two loops. One to count how many times each value occured. And one to find which one occured the most.
Optionally if you want to handle multiple high values then replace the second loop with this.
var answer = [null];
// for each value if the occurances is equal then add it to the array
// else if the occurance is higher then the current highest occurance.
// then set that as the current array of values.
$.each(data, function(key, val) {
if (val === data[answer[0]]) {
answer.push(key);
} else if (val > data[answer[0]]) {
answer = [key];
}
}
return answer;
Try this:
var array = ['1','2','3', '3','4','5', '3', '4', '5', '5'],
l = array.length,
col = {},
current,
max = {cnt:0, values:[]};
while(l--){
current = array[l];
col[current] = (col[current] || 0) + 1;
if(col[current] > max.cnt){
max = {cnt:col[current], values: [current]};
}else if(col[current] === max.cnt){
max.values.push(current);
}
}
console.log(
max.cnt === 1 ?
'they are all different' :
max.values.join(',') + ' occured ' + max.cnt + ' times'
);
You probably want to use something like this:
var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var counts = {};
for(var i = 0; i< arr.length; i++) {
var num = arr[i];
counts[num] = counts[num] ? counts[num]+1 : 1;
}
Now, you'll have an object that has a count of all the members in the array.
console.log(counts[5]); // logs '3'