javascript using reduce function - javascript

I have the below array
["0,5,p1", "24,29,p2", "78,83,p2", "78,83,p3", "162,167,p2" ]
i want the output as ["5,p1","10,p2","5,p3"] , so p1..3 are video files paying time with start and end time . 0,5 mean p1 profile played for 5 sec and so on.
I want to know what profile take what time in total using ECMA script map,reduce function. Here is what i tried but it doesnt work:
var ca = uniqueArray.reduce(function(pval, elem) {
var spl = elem.split(',');
var difference = Math.round(spl[1] - spl[0]);
return difference;
},elem.split(',')[3]);

I dont think it can be done in one pass, but I could be wrong. I'd go for a 2 step...
Reduce the array to get unique map of pX values
Map the result back to an array in the required format
var input = ["0,5,p1", "24,29,p2", "78,83,p2", "78,83,p3", "162,167,p2" ]
var step1 = input.reduce(function(p,c){
var parts = c.split(",");
if(!p[parts[2]])
p[parts[2]] = 0;
p[parts[2]] += parseInt(parts[1],10) - parseInt(parts[0],10);
return p;
},{});
var result = Object.keys(step1).map(function(e){
return step1[e] + "," + e;
});
console.log(result);

You could use es6 map:
arrayWithNumbers.map(a => {var spl = a.split(','); return (spl[1] - spl[0]) + "," + spl[2]})

For a single loop approach, you could use a hash table for same third parts, like 'p1'. If a hash is given, then update the value with the actual delta.
var array = ["0,5,p1", "24,29,p2", "78,83,p2", "78,83,p3", "162,167,p2"],
hash = Object.create(null),
result = array.reduce(function(r, a) {
var parts = a.split(','),
delta = parts[1] - parts[0],
key = parts[2];
if (!(key in hash)) {
hash[key] = r.push([delta, key].join()) - 1;
return r;
}
r[hash[key]] = [+r[hash[key]].split(',')[0] + delta, key].join();
return r;
}, []);
console.log(result);

I have updated the code. Please check now.
var ca = ["0,5,p1", "24,29,p2", "78,83,p2", "78,83,p3", "162,167,p2" ] .reduce(function(result, elem) {
var spl = elem.split(',');
var difference = Math.round(spl[1] - spl[0]);
var found = false
for (var i = 0 ; i < result.length; i++) {
if (result[i].split(',')[1] == spl[2]) {
result[i] = parseInt(result[i].split(',')[0]) + difference+","+spl[2];
found = true;
}
}
if (!found) result.push(difference+","+spl[2]);
return result;
},[]);
console.log("modified array",ca);

Related

Return multiple strings from function based on variable number

I have a string
var str = 'string'
I have a multiplier
var mult = 3
I want to return stringstringstring
The mult will change. Basically mult is kind of like a power but this is a string not a number. And I need to return multiple strings. I'm thinking of looping where mult = the number of times to loop and each would conceptually 'push' but I don't want an array or something like =+ but not a number. I'm thinking I could have the output push to an array the number of times = to mult, and then join the array - but I don't know if join is possible without a delimiter. I'm new at javascript and the below doesn't work but it's what I'm thinking. There's also no ability to input a function in the place I'm running javascript and also no libraries.
var loop = {
var str = 'string'
var arr = [];
var mult = 3;
var i = 0
for (i = 0, mult-1, i++) {
arr.push('string'[i]);
}
}
var finalString = arr.join(''); // I don't know how to get it out of an object first before joining
Not sure if what I want is ridiculous or if it's at all possible
You mean something like below,
var str = 'string'
var mult = 3
var str2 = ''
for(i = 0; i < mult; i++) {
str2 += str
}
console.log(str2)
var str = 'string'
var mult = 3;
var sol =""
while(mult--) {
sol +=str;
}
console.log(sol)
Using resusable function:
const concatStr= (str, mult)=>{
var sol =""
while(mult--) {
sol +=str;
}
console.log(sol)
}
concatStr("string",3)
Using the inbuilt Array.from method:
var str = "string"
var mult = 3
var sol = Array.from({length: mult}, ()=> str).join("")
console.log(sol)
function concatString(str, mult) {
var result = ''
for(i = 0; i < mult; i++) {
result = result.concat(str);
}
return result;
}
const value = concatString('string', 3);
console.log(value);
Also you can use array inbuilt methods,
const mult = 3, displayVal = 'str';
Array(mult).fill(displayVal).join('');
// the string object has a repeat method
console.log('string'.repeat(3));

How can I make this to a loop?

How can I make this to a loop? the array tabProsent contains 70 numbers.
var startVerdi=1000;
if(slider.value==tab[0]){
output2.innerHTML = startVerdi*tabProsent[0];
}
if(slider.value==tab[1]){
output2.innerHTML = startVerdi*tabProsent[0]*tabProsent[1];
}
if(slider.value==tab[2]){
output2.innerHTML = startVerdi*tabProsent[0]*tabProsent[1]*tabProsent[2];
}
if(slider.value==tab[3]){
output2.innerHTML = startVerdi*tabProsent[0]*tabProsent[1]*tabProsent[2]*tabProsent[3];
}
You can use the array methods indexOf(), slice(), and reduce():
var startVerdi=1000;
var index = tab.indexOf(slider.value);
if (index !== -1) {
output2.innerHTML = tabProsent.slice(0, index + 1).reduce(
(acc, cur) => acc * cur, startVerdi
);
}
You could do something like this -
var startVerdi=1000;
for(let i=0;i<70;i++){ // check for tab[0], tab[1] and so on...
if(slider.value == tab[i]){
let temp = startVerdi;
for(let j=0;j<=i;j++){
temp = temp * tabProsent[j] // multiply with tabProsent[0], tabProsent[1] and so on...
}
output2.innerHTML = temp;
}
}
Here is a simple and understandable method : you need two loops:
One to find the index of tab that corresponds to the slider value
Another (inner loop) to create the product of values of tabProsent that are smaller or equal to the index of tab:
const MAX_TAB_IDX = 69; // 0 to 69 gives 70 values
let startVerdi=1000;
for(let idx=0; idx<=MAX_TAB_IDX; idx++) { // First loop
if(slider.value == tab[idx]) { // We found it!! Lets calculate the product..
let product=1;
for(let subidx=0; subidx <= idx; subidx ++) // Second loop
product *= tabProsent[subidx];
output2.innerHTML = startVerdi * product;
break; // This is to stop the loop!
}
}
There are other more elegant ways (for example, using slice and map functions) - this is so you can understand how it works.
Based on the comments under the question and answer from Patrick Roberts, here is working example:
// Prepare data:
var startVerdi = 1000;
let tabProsent = [];
for (let i = 0; i < 70; i++) tabProsent.push(Math.random() * 0.13 + 1);
function sliderChanged(val) {
const index = val - 1950;
const total = tabProsent.slice(0, index + 1).reduce(
(acc, cur) => acc * cur, startVerdi
);
document.getElementById('result').innerHTML = total;
}
<input type="range" min="1950" max="2020" onchange="sliderChanged(this.value)" oninput="sliderChanged(this.value)" />
<label id="result">?</label>

javascript - sorting array by order of another array

My goal is to sort this div
<div id="myDiv">3xOrange;2xBlue;1xRed;1xRed;1xRed;1xOrange;2xBlue;3xRed;1xBlue;1xRed;2xBlue;3xRed;1xBlue;1xRed;2xBlue;3xRed;1xBlue;1xRed;2xBlue;3xRed;1xBlue;1xRed;2xOrange;3xRed;1xBlue;1xRed;2xBlue;3xRed;1xBlue;1xRed;20xBlue;33xRed;20xBlue;33xRed;2xBlue;3xRed;51xBlue;51xRed;</div>
by another div in this order
<div id="array"> Blue: 1,Red: 2,Orange: 3, </div>
So my Wanted result is to get result like this
2xBlue;1xBlue;1xBlue;2xBlue;3xRed;3xRed;1xRed;1xRed;2xOrange;3xOrange ......
I aware for the first div needs to be used string split something like this .split('x')[1];
So far I have this code:
var init_arr;
var scorer;
window.onload=function() {
scorer=document.getElementById("array").innerHTML;
init_arr = document.getElementById("myDiv").innerHTML;
var final_arr = init_arr.sort(function(a,b) {
return scorer[a]-scorer[b];
});
}
alert(final_arr);
but getting error TypeError: init_arr.sort is not a function I guess init_arr and scorer are objects not strings
Please Help
This answer deletes the rest of the strings with ; or ,, treats array like a part of a JSON string, and sort with the part after the x.
window.onload = function() {
var init_arr = document.getElementById("myDiv").innerHTML.split(';'),
scorer = JSON.parse('{' + document.getElementById("array").innerHTML + '}');
init_arr.sort(function(a, b) {
var aa = a.split('x')[1],
bb = b.split('x')[1];
return scorer[aa] - scorer[bb];
});
alert(init_arr);
};
<div id="myDiv">3xOrange;2xBlue;1xRed;1xRed;1xRed;1xOrange;2xBlue;3xRed;1xBlue;1xRed;2xBlue;3xRed;1xBlue;1xRed;2xBlue;3xRed;1xBlue;1xRed;2xBlue;3xRed;1xBlue;1xRed;2xOrange;3xRed;1xBlue;1xRed;2xBlue;3xRed;1xBlue;1xRed;20xBlue;33xRed;20xBlue;33xRed;2xBlue;3xRed;51xBlue;51xRed</div>
<div id="array">"Blue": 1,"Red": 2,"Orange": 3</div>
But I really suggest to use real arrays for data and objects for sorting order. And not any parts of HTML code.
Well, I felt dummy after playing around to help you after seeing the first answer, but here it goes.
<div id="myDiv">3xOrange;2xBlue;1xRed;1xRed;1xRed;1xOrange;2xBlue;3xRed;1xBlue;1xRed;2xBlue;3xRed;1xBlue;1xRed;2xBlue;3xRed;1xBlue;1xRed;2xBlue;3xRed;1xBlue;1xRed;2xOrange;3xRed;1xBlue;1xRed;2xBlue;3xRed;1xBlue;1xRed;20xBlue;33xRed;20xBlue;33xRed;2xBlue;3xRed;51xBlue;51xRed;</div>
<div id="array"></div>
var init;
var final;
var scorer;
scorer = document.getElementById("array");
init = document.getElementById("myDiv");
init = init.textContent.split(/\;/);
init = init.filter(function(item) {
return item.length > 0;
})
.map(function(item) {
item = item.split(/x/);
var obj = {
color: item[1],
amount: parseInt(item[0])
}
return obj;
});
final = init.reduce(function(scored, item) {
if(scored[item.color] === undefined) {
scored[item.color] = 0;
}
scored[item.color] += item.amount;
return scored;
}, {});
final = Object.keys(final)
.sort(function(item1, item2) {
return final[item1].amount - final[item2].amount;
})
.map(function(key) {
return key + ' :' + final[key];
});
scorer.textContent = final.join(', ');
At least it was funny to play with map, filter, reduce and sort
This is the sort of thing you could do:
function sort() {
var scorer;
var scorerLookup;
var sortedLookup;
//First we figure out the sort order
scorer = document.getElementById("array").innerHTML.split(',');
scorer.sort(function(a, b) {
aVal = parseInt(a.split(':')[1].trim());
bVal = parseInt(b.split(':')[1].trim());
return aVal - bVal;
});
console.log(scorer);
//Now put the sort order into an object so we can easily lookup values
scorerLookup = {};
for (var i = 0; i < scorer.length; i++) {
var tempVal = scorer[i].split(':');
scorerLookup[tempVal[0].trim()] = parseInt(tempVal[1].trim());
}
console.log(scorerLookup);
//Now sort the main list
init_arr = document.getElementById("myDiv").innerHTML.split(';');
init_arr.sort(function(a, b) {
aVal = scorerLookup[a.split('x')[1]];
bVal = scorerLookup[b.split('x')[1]];
return aVal - bVal;
});
console.log(init_arr);
}
window.onload=sort();
It needs more error trapping really (for blank values, etc) - but it should give you the general idea.

Adding commas, decimal to number output javascript

I'm using the following code to count up from a starting number. What I need is to insert commas in the appropriate places (thousands) and put a decimal point in front of the last two digits.
function createCounter(elementId,start,end,totalTime,callback)
{
var jTarget=jQuery("#"+elementId);
var interval=totalTime/(end-start);
var intervalId;
var current=start;
var f=function(){
jTarget.text(current);
if(current==end)
{
clearInterval(intervalId);
if(callback)
{
callback();
}
}
++current;
}
intervalId=setInterval(f,interval);
f();
}
jQuery(document).ready(function(){
createCounter("counter",12714086+'',9999999999,10000000000000,function(){
alert("finished")
})
})
Executed here: http://jsfiddle.net/blackessej/TT8BH/3/
var s = 121221;
Use the function insertDecimalPoints(s.toFixed(2));
and you get 1,212.21
function insertDecimalPoints(s) {
var l = s.length;
var res = ""+s[0];
console.log(res);
for (var i=1;i<l-1;i++)
{
if ((l-i)%3==0)
res+= ",";
res+=s[i];
}
res+=s[l-1];
res = res.replace(',.','.');
return res;
}
Check out this page for explanations on slice(), split(), and substring(), as well as other String Object functions.
var num = 3874923.12 + ''; //converts to a string
numArray = num.split('.'); //numArray[0] = 3874923 | numArray[1] = 12;
commaNumber = '';
i = numArray[0].length;
do
{
//we don't want to start slicing from a negative number. The following line sets sliceStart to 0 if i < 0. Otherwise, sliceStart = i
sliceStart = (i-3 >= 0) ? i-3 : 0;
//we're slicing from the right side of numArray[0] because i = the length of the numArray[0] string.
var setOf3 = numArray[0].slice(sliceStart, i);
commaNumber = setOf3 + ',' + commaNumber; //prepend the new setOf3 in front, along with that comma you want
i -= 3; //decrement i by 3 so that the next iteration of the loop slices the next set of 3 numbers
}
while(i >= 0)
//result at this point: 3,874,923,
//remove the trailing comma
commaNumber = commaNumber.substring(0,commaNumber.length-1);
//add the decimal to the end
commaNumber += '.' + numArray[1];
//voila!
This function can be used for if not working locale somite
number =1000.234;
number=insertDecimalPoints(number.toFixed(3));
function insertDecimalPoints(s) {
console.log(s);
var temaparray = s.split(".");
s = temaparray[0];
var l = s.length;
var res = ""//+s[0];
console.log(res);
for (var i=0;i<l-1;i++)
{
if ((l-i)%3==0 && l>3)
res+= ",";
res+=s[i];
}
res+=s[l-1];
res =res +"."+temaparray[1];
return res;
}
function convertDollar(number) {
var num =parseFloat(number);
var n = num.toFixed(2);
var q =Math.floor(num);
var z=parseFloat((num).toFixed(2)).toLocaleString();
var p=(parseFloat(n)-parseFloat(q)).toFixed(2).toString().replace("0.", ".");
return z+p;
}

Transform a string into array using javascript

I have a string like this:
string = "locations[0][street]=street&locations[0][street_no]=
34&locations[1][street]=AnotherStreet&locations[1][street_no]=43";
What must I do with this string so i can play with locations[][] as I wish?
You could write a parser:
var myStr = "locations[0][street]=street&locations[0][street_no]=34&locations[1][street]=AnotherStreet&locations[1][street_no]=43";
function parseArray(str) {
var arr = new Array();
var tmp = myStr.split('&');
var lastIdx;
for (var i = 0; i < tmp.length; i++) {
var parts = tmp[i].split('=');
var m = parts[0].match(/\[[\w]+\]/g);
var idx = m[0].substring(1, m[0].length - 1);
var key = m[1].substring(1, m[1].length - 1);
if (lastIdx != idx) {
lastIdx = idx;
arr.push({});
}
arr[idx * 1][key] = parts[1];
}
return arr;
}
var myArr = parseArray(myStr);
As Shadow wizard said, using split and eval seems to be the solution.
You need to initialize locations first, if you want to avoid an error.
stringArray=string.split("&");
for (var i=0;i<stringArray.length;i++){
eval(stringArray[i]);
}
However, you might need to pay attention to what street and street_no are.
As is, it will produce an error because street is not defined.
Edit: and you'll need to fully initialize locations with as many item as you'll have to avoid an error.

Categories