I have array like this in JavaScript
var a = [1,2,3,4,5,"4","12","2",6,7,"4",3,"2"];
My questions are
How do I split the array to change, (comma) to ";"
How do I return the number of strings in the array as well as return total value regardless of variable type.
How do I return the average value (regardless of variable type again)
Answering Question 1
1.Convert it to a string
var x=a.toString();
2.Perform a global replace
var y= x.replace(/,/g,";");
3.This gives you "1;2;3;4;5;4;12;2;6;7;4;3;2"
For Question 2
Simply use the a.length method.This will give you the total number of elements.I'm not sure about the String elements part.
Change array separator:
a.join(';');
as referenced here
Number of strings in array:
var stringCount = 0;
for (var i = 0; i < a.length; i++){
if (typeof a[i] === 'string'){
stringCount++;
}
}
alert("The number of strings is: " + stringCount);
Test it here: https://jsfiddle.net/6c42nugy/2/
Number of all elements in array:
var entireLength = a.length;
Percentage per type in comparison to whole
var stringPerc = (stringCount)/(stringCount + entireLength)
var otherPerc = (entireLength - stringCount)/(stringCount + entireLength)
Use a.join(';'); to convert the array into a string separated by semicolons.
To return the number of strings in the array, simply iterate through it and use toString.call() like this:
var total = 0;
for (var i = 0, n = a.length; i < n; i++) {
if (toString.call(a[i]) === '[object String]') total++;
}
To simply return the total number of items, you can do a.length.
If you want the total value as in all the elements summed, you can do this:
var total = 0;
for (var i = 0, n = a.length; i < n; i++) {
total += parseInt(a[i]);
}
If you want the average, just take the code above and do total / a.length;.
Here is my version:
var a = [1,2,3,4,5,"4","12","2",6,7,"4",3,"2"], sum = 0, strings = 0;
var joined = a.join(';');
console.log("Joined: " + joined);
for (var i = 0; i < a.length; i++) {
sum += parseInt(a[i]);
if (typeof a[i] === "string") {
strings++;
}
}
var avg = sum / a.length;
console.log('Sum: ' + sum);
console.log('Average: ' + avg);
console.log('Strings: ' + strings);
And link to JSFiddle.
All results in one loop.
0 ... n-4: Data
n-3: Count of all strings
n-2: Sum
n-1: Average
var data = [1, 2, 3, 4, 5, "4", "12", "2", 6, 7, "4", 3, "2"],
result = data.concat(data.reduce(function (r, a, i) {
typeof a === 'string' && r[0]++;
r[1] += +a;
r[2] = r[1] / i;
return r;
}, [0, 0, 0])).join(';');
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
Related
The question originates from this leetcode question: https://leetcode.com/problems/maximum-subarray/
But instead of returning the largest sum, I want to return the subarray that has the largest sum. For example, [-2,1,-3,4,-1,2,1,-5,4], the largest sum is 6 as in [4,-1,2,1] . Here I want to return [4,-1,2,1] not 6 the number.
Here is my attempt:
var maxSubArray = function(nums) {
let max = -Infinity
let sum = 0
const results = []
for(const num of nums) {
results.push(num)
sum += num
max = Math.max(sum, max)
if(sum < 0) {
sum = 0
results.length = 0
}
}
return results
};
maxSubArray([-2,1,-3,4,-1,2,1,-5,4])
However it returns an incorrect answer - [ 4, -1, 2, 1, -5, 4 ]. I found it really hard to implement this since it is hard to determine whether or not we should keep adding the subsequent item in the results array.
Wondering if anyone would like to give it a try.
In this tutorial, by using Kadane’s algorithm and maintain indices whenever we get the maximum sum.
var maxSubArray = function(nums) {
var max_so_far = 0, max_ending_here = 0;
var startIndex = -1;
var endIndex = -1;
for(var i = 0; i < nums.length; i++) {
if (nums[i] > max_ending_here + nums[i]) {
startIndex = i;
max_ending_here = nums[i];
} else
max_ending_here = max_ending_here + nums[i];
if (max_so_far < max_ending_here) {
max_so_far = max_ending_here;
endIndex = i;
}
}
return nums.slice(startIndex, endIndex + 1);
};
console.log(maxSubArray([-2,1,-3,4,-1,2,1,-5,4]))
Thanks baeldung's blog.
This page shows how to maintain indices whenever we get the maximum sum.
No JS, so I copy Java code here:
static void maxSubArraySum(int a[], int size)
{
int max_so_far = Integer.MIN_VALUE,
max_ending_here = 0,start = 0,
end = 0, s = 0;
for (int i = 0; i < size; i++)
{
max_ending_here += a[i];
if (max_so_far < max_ending_here)
{
max_so_far = max_ending_here;
start = s;
end = i;
}
if (max_ending_here < 0)
{
max_ending_here = 0;
s = i + 1;
}
}
System.out.println("Maximum contiguous sum is "
+ max_so_far);
System.out.println("Starting index " + start);
System.out.println("Ending index " + end);
}
my array from user input: [1,2,3,4]
what I want:
[1,2,3]*[2,3,4]
(1*2) + (2*3) + (3*4) = 20
what I have so far:
var array = [];
var number= document.getElementById("number").value; //this is where user inputs the number for my array
var sum = 0;
for (var i = 0; i< number.length; i++){
array.push(parseInt(number[i]));
var first= number[i-1];
var second = number[i+1];
sum += (first*second);
}
console.log(sum);
that is my solution with reduce method of array
[1, 2, 3, 4].reduce((a, c, i, s) => (s[i + 1] ? c * s[i + 1] + a : a), 0);
No need for an array for this.
In the following pattern: (1*2) + (2*3) + (3*4) you can see how this can occur using for loop without array.
Following works:
var number= parseInt(document.getElementById("number").value); //this is where user inputs the number for my array
var sum=0;
for (var i = 1; i< number; i++){
sum += i*(i+1);
}
console.log(sum);
You could use slice to get subsets of the arrays and then use reduce to create the sum like this:
const arr = [1,2,3,4]
const first = arr.slice(0, -1)
const last = arr.slice(1, arr.length)
const result = first.reduce((acc, num, idx) => acc + num * last[idx], 0)
console.log(result)
How do I divide the sum with 2 after a loop, so I get the value 38? I want to print out the answer in an alert box.
My Javascript code:
var nums = ['1','75'];
var sum = 0;
for(var i=0; i < nums.length; i++){
sum += parseInt(nums[i]);
}
alert(sum);
Or if I have the values 1, 2, 3, 4, I want to get the sum (in this case 10) in the loop and divide it with 2 and print out it in an alert box.
//variable declaration and loop above
alert(sum/2);
You need to divide by 2 then...
var nums = ['1','75'];
var sum = 0;
for(var i=0; i < nums.length; i++){
sum += parseInt(nums[i]);
}
sum /= 2;
alert(sum);
var nums = ['1','75'];
let sumDiv2 = (nums)=> {
var sum = 0;
for(var i=0; i < nums.length; i++){
sum += Number(nums[i]);
}
return sum
}
alert(sumDiv2(nums)/2);
var nums = ['1','75'];
var sum = 0;
for(var i=0; i < nums.length; i++){
sum += parseInt(nums[i]);
}
alert(sum/2);
This isn't complex to solve.
Using array reduce method you can do like below
var arr = ["1", "67"];
var divide = arr.reduce(function (acc, ele) {
return acc += +ele; // To convert element from string to array use +
}, 0) / 2;
console.log(divide);
You can do it on 1 line.
var nums = ['1','2', '3', '4'];
var result = nums.reduce((el, acc) => parseInt(el) + parseInt(acc), 0) / 2;
console.log(result);
var nums = ['1','75'];
var sum = 0;
for(var i=0; i < nums.length; i++){
sum += parseInt(nums[i]);
}
alert(sum/2);
You can try this without any loop. Short, simple and stylish:
var arr=['1', '75'],
sum_2=arr.reduce(function(a,b){return a*1+b*1;},0)/2;
alert(sum_2);
console.log(['1','2'].reduce((p,c) => +p + +c, 0) / 2)
// ^ ^ ^ ^ ^
// | | | | |
// "p" as "previous"_| | |____| |_first "p" value
// | |
// "c" as "current"_| |_convert strings to integers
Run the snippet; what happens:
.reduce() starts on the ['1','2']
In the first call to the inner function ((p,c) => +p + +c) the value of p(revious) is 0, as the second argument passed to the .reduce(), and value of the c(urrent) is '1', the first array element; the 0 + +'1' executes, resulting in 1
In the second call to the inner function the value of p is 1 - from previous execution, and the value of c is '2'; the 1 + +'2' executes, resulting in 3
As here are no more items in the array, the final result of .reduce() call gives as 3, which is then divided by 2 in 3 / 2, resulting in 1.5
Unary operator + preceding string (+'1', '+'2'`) converts the string into integers.
You could divide the sum by 2.
BTW, while you have already integer values as strings, you could use an unary plus + for a conversion to number.
sum += +nums[i];
// ^
var nums = ['1', '75'],
sum = 0,
i;
for (i = 0; i < nums.length; i++) {
sum += +nums[i];
}
alert(sum / 2);
To shuffle a string, I could use something like this
String.prototype.shuffle = function () {
var arr = this.split("");
var len = arr.length;
for (var n = len - 1; n > 0; n--) {
m = Math.floor(Math.random() * (n + 1));
tmp = arr[n];
arr[n] = arr[m];
arr[m] = tmp;
}
return arr.join("");
}
But how could I randomly space it with n characters, while preserving the string order?
For example:
"test" => "t-es--t"
"test" => "-t-e-st"
"test" => "te--st-"
I've thought about creating a list from the string, generating a random number to represent an index, and then shifting the list to the left, but is there a better way to do this?
This will insert n characters char randomly into the string. If char is missing, it defaults to a space:
String.prototype.shuffle = function(n, char) {
var arr = this.split(''),
char= char || ' ';
while(n--) {
arr.splice(Math.floor(Math.random() * (arr.length+1)), 0, char);
}
return arr.join('');
} //shuffle
This Fiddle shows the relative random distribution using the method.
If you want a truly unbiased solution that produces all possibilities equally likely, and have access to a perfect random number generator (which is a whole other topic), there's a fairly easy solution. Let's define some terms:
m = number of characters in the string
k = number of spaces you want to insert (you called this n)
Consider one solution to this problem with m=7 and k=3:
0123456789
cab ba g e
What the problem essentially amounts to is choosing k different numbers from among a set of m+k numbers. There are (m+k)!/(m!*k!) possibilities. This is the concept of combinations and is similar to the stars-and-bars problem in the Wikipedia page. (To get an unbiased generator you would need a random number generator with the number of state values much higher than this number of possibilities. But I said RNGs are a whole other topic.)
Here's an example in Python showing all possibilities:
import itertools
def show_all(s, k):
# show all combinations of k spaces inserted into string s
m = len(s)
for sample in itertools.combinations(range(m+k),k):
jprev = 0
out = ''
for ispace, i in enumerate(sample):
j = i-ispace # adjust index by number of spaces used
out += s[jprev:j] + ' '
jprev = j
out += s[jprev:]
yield sample, out
for sample, out in show_all('shoe',2):
print sample,':'+out+':'
output:
(0, 1) : shoe:
(0, 2) : s hoe:
(0, 3) : sh oe:
(0, 4) : sho e:
(0, 5) : shoe :
(1, 2) :s hoe:
(1, 3) :s h oe:
(1, 4) :s ho e:
(1, 5) :s hoe :
(2, 3) :sh oe:
(2, 4) :sh o e:
(2, 5) :sh oe :
(3, 4) :sho e:
(3, 5) :sho e :
(4, 5) :shoe :
Now the problem becomes one of generating a random combination. In Python this is part of the itertools recipes:
def random_combination_with_replacement(iterable, r):
"Random selection from itertools.combinations_with_replacement(iterable, r)"
pool = tuple(iterable)
n = len(pool)
indices = sorted(random.randrange(n) for i in xrange(r))
return tuple(pool[i] for i in indices))
In Javascript we have to implement this ourselves, which we can do using Robert Floyd's algorithm for sampling without replacement:
pseudocode:
initialize set S to empty
for J := N-M + 1 to N do
T := RandInt(1, J)
if T is not in S then
insert T in S
else
insert J in S
Javascript:
function random_comb(r, n, m)
{
/* Generate a combination of m distinct random integers between 0 and n-1
using Floyd's algorithm
r: random generation function
such that r(k) generates an integer in the range [0, k-1]
*/
var S = {};
var out = [];
for (var i = 0; i < m; ++i)
{
var j = i+(n-m);
var t = r(j+1);
var item = (t in S) ? j : t;
S[item] = 1;
out.push(item);
}
return out.sort();
}
Now let's put it all together, ignoring the fact that Math.random() is inadequate:
var r = function(n) { return Math.floor(Math.random()*n); }
function random_comb(r, n, m)
{
/* Generate a combination of m distinct random integers between 0 and n-1
using Floyd's algorithm
r: random generation function
such that r(k) generates an integer in the range [0, k-1]
*/
var S = {};
var out = [];
for (var i = 0; i < m; ++i)
{
var j = i+(n-m);
var t = r(j+1);
var item = (t in S) ? j : t;
S[item] = 1;
out.push(item);
}
return out.sort();
}
function random_insert(r, s, k, c)
{
/* randomly insert k instances of character c into string s */
var m = s.length;
var S = random_comb(r, m+k, k);
var jprev = 0;
var out = '';
for (var ispace = 0; ispace < k; ++ispace)
{
var i = S[ispace];
var j = i - ispace; // adjust index by # of spaces
out += s.slice(jprev,j) + c;
jprev = j;
}
out += s.slice(jprev);
return out;
}
var word = 'shoe';
var results = [];
for (var i = 0; i < 10; ++i)
{
results.push(random_insert(r,word, 2, '-'));
}
var tally = {};
for (var i = 0; i < 100000; ++i)
{
var s = random_insert(r,word,2,'-');
tally[s] = (s in tally) ? (tally[s] + 1) : 1;
}
for (var s in tally)
{
results.push(s+": "+tally[s]);
}
for (var i = 0; i < results.length; ++i)
{
$("#results").append(results[i]+'<br>');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="results"></div>
Working jsFiddle
Even though I loved #Barmar 's idea..
You can do it by simply looping and randomizing positions to insert the spaces..
String.prototype.insertSpaces = function (n, char) {
var str = this;
for(var i = 0; i < n; i++){
var randPos = Math.floor(Math.random() * (str.length + 1)); // get random index to insert
str = str.substring(0, randPos) + char + str.substring(randPos, str.legnth); // insert the repeated sting
}
return str;
}
function addRandomSpaces(str,n,char){
for (var newstr="", i=0; i<str.length;){
if (n && Math.random()<0.5) {
newstr += char;
n--;
} else {
newstr += str[i++];
}
}
while(n--){
newstr += char;
}
return newstr;
}
Here's a function that will loop through a given string str, adding n instances of char at random places. If when it finishes, n items haven't been added, it adds finishes them at the end.
You can use the slice function insert the new character:
var x = "this is phrase";
var y = " a";
[x.slice(0,7), y, x.slice(7)].join('');
Result: this is a phrase
Something like this:
String.prototype.shuffle2 = function() {
'use strict';
var numberOfSpaces = Math.floor(Math.random() * (this.length - 1));
var word = this;
for (var i = 0; i < numberOfSpaces; i++) {
var index = Math.floor(Math.random() * (this.length - 1));
word = [word.slice(0,index), '-', word.slice(index)].join('');
}
return word;
};
Greetings!
String.prototype.addspace = function () {
var arr = this.split("");
var len = arr.length;
maxSp = 4;
for(var i = 0; i <= len; i++){
m = Math.floor(Math.random() * (maxSp + 1));
for(var j = 0; j < m ; j++){
arr.splice(i,0," ");
}
len += m;
i +=m;
}
return arr.join("");
}
alert("Juanito".addspace().shuffle());
I'm trying to write a small JS program. For every value in array B, I want to find the consecutive values in A that sum to that value of B.
I'm trying to print the element in the array A such that it matches the consecutive sum in array B.
I wrote the code on this JSFiddle page but I'm not sure if B contains N elements...
Could you tell me how to write it in jQuery? Output it should element in myArray such that it matches the consecutive sum in myOtherArray
myArray[0] + myArray1 will not work if it contains N elements.
var myArray = [ 2, 3, 4 ];
var myOtherArray = [ 5, 6, 7 ];
for ( var i = 0; i < myOtherArray.length; i++ ) {
for ( var j = 0; j < myArray.length; j++ ) {
if ( myOtherArray[i] == myArray[0] +myArray[1] ) {
console.log (myArray[ i ]);
}
else if(myOtherArray[i] == myArray[1] +myArray[2]) {
console.log (myArray[ i ]);
}
else{
console.log ("no matching");
}
}
}
I'm taking a gamble by answering this.. but I'm assuming that you want to keep on adding two indexes within your array that are next to each other, to see if they'd equal any value in your second array?
Also, I have no idea why you're using a nested loop. You only need to traverse one array, not two.
var myArray = [ 2, 3, 4 ];
var myOtherArray = [ 5, 6, 7 ];
var sum = 0;
for ( var i = 0; i < myArray.length-1; i++ ) {
sum = myArray[i] +myArray[i+1];
if (myOtherArray.indexOf[sum] != -1 ) {
console.log ("matching");
}
else {
console.log ("no matching");
}
}
the result should spit out "matching" twice.
Because 2+3 = 5, which exists in the second array. And 3+4 = 7, which also exists in the second array.
Since the criteria is not well defined I believe this might be similar to what you are looking for
var sum = 0;
for (var j = 0; j < myArray.length; j++) {
sum += myArray[j];
var isMatch = myOtherArray.indexOf(sum) > -1,
matchText = isMatch ? ' true' : ' false';
$('body').append('Match for ' + sum + ' is' + matchText + '<br>')
}
It sums all elements within the array up to the current index and checks if that value exists in other array
DEMO
Answer to how i understood the question: http://jsfiddle.net/qqqs8aLc/1/
var A = [ 5, 6, 7 ];
var B = [ 2, 3, 4 ];
var Alen = A.length;
var Blen = B.length;
for(var i=0; i < Alen; i++){
for(var j=0; j < Blen; j++){
if(A[i] == (B[j] + B[j+1])){
console.log("%d = (%d, %d)",A[i], B[j], B[j+1]);
}
}
}