javascript - change every three items in a step of 6 iteration - javascript

I have an array of items (length could be different). I need to differently change every first three items, then fourth and fifth, then sixth and start again..
For example:
var arr = [1,2,3,4,5,6,7,9,10];
var newArr = arr.map(function (value, index) {
// indexes 1,2,3 value+1
// indexes 4,5 value+2
// index 6 value+3
// indexes 7,8,9 value+1
// indexes 10,11 value+2
// starting over and over...
});
console.log(newArr);
Thanks!

You can use modulus and some conditions to return what you want
var arr = [1,2,3,4,5,6,7,9,10];
var newArr = arr.map(function (value, index) {
var modulo = (index % 6) + 1,
added = 1;
if ( modulo === 4 || modulo === 5 ) added = 2;
if ( modulo === 6 ) added = 3;
return value + added;
});
document.body.innerHTML = '<pre>' + JSON.stringify(newArr, null, 4) + '</pre>';
Golfed, just for fun
var newArr = arr.map(function (v, i) {
return v + ([3,4].indexOf(i%6) != -1 ? 2 : (i%6) === 5 ? 3 : 1);
});

I think you meant indexes instead of values. If this is the case, then this should work:
var arr = [1, 2, 3, 4, 5, 6, 7, 9, 10];
var newArr = arr.map(function(value, index) {
var m = index % 6;
if (m < 3) {
return value + 1;
}
if (m < 5) {
return value + 2;
} else {
return value + 3;
}
});
alert(newArr);

var arr = [1,2,3,4,5,6,7,9,10];
func_123 = function( value, index ){
console.log( 'stuff of first three ' + value + ' ' + index )};
func_45 = function( value, index ){
console.log( 'stuff of four & five ' + value + ' ' + index )};
func_6 = function( value, index ){
console.log( 'stuff of six ' + value + ' ' + index )};
var newArr = arr.map(function (value, index) {
[ func_123, func_123, func_123, func_45, func_45, func_6 ][ index % 6 ]( value, index )});

Related

Creating various arrays from a string using LOOPS

I have a string of values
"000111111122222223333333444455556666"
How could I use a loop to produce one array for index values from 0 to 3 (create an array of [000] and then another array of index values from 3 to 10, 10 to 17, 17 to 24, producing eg. [1111111, 2222222, 333333] and then another loop to produce an array of index values from 24 to 28, 28 to 32, 32 to 36, producing eg. [4444, 5555, 6666])?
So in total 3 different arrays have been created using three different for loops.
array1 = [000]
array2 = [1111111, 2222222, 333333]
array3 = [4444, 5555, 6666]
You may wish to try something line this (only a schematic solution!):
var l_Input = "000111111122222223333333444455556666" ;
var l_Array_1 = [] ;
var l_Array_2 = [] ;
var l_Array_3 = [] ;
var l_One_Char ;
for (var i = 0 ; i < l_Input.length ; i++) {
l_One_Char = l_Input.substring(i,i) ;
if (i < 3) {
l_Array_1.push(l_One_Char) ;
continue ;
}
if (i >= 3 && i < 10) {
l_Array_2.push(l_One_Char) ;
continue ;
}
:
:
}
I think this would work.
const str = '000111111122222223333333444455556666';
function makeArr(str, item) {
let firstIndex = str.indexOf(item);
let lastIndex = str.lastIndexOf(item) + 1;
return [ str.substring(firstIndex, lastIndex) ];
}
const first = makeArr(str, 0);
const second = [].concat(makeArr(str, 1))
.concat(makeArr(str, 2))
.concat(makeArr(str, 3));
const third = [].concat(makeArr(str, 4))
.concat(makeArr(str, 3))
.concat(makeArr(str, 3));
You could map the sub strings.
var str = '000111111122222223333333444455556666',
parts = [[3], [7, 7, 7], [4, 4, 4]],
result = parts.map((i => a => a.map(l => str.slice(i, i += l)))(0));
console.log(result);
function split(string, start, end) {
var result = [],
substring = string[start],
split;
for (var i = start + 1; i < end; i++) {
var char = string[i];
if (char === substring[0])
substring += char;
else {
result.push(substring);
substring = char;
}
}
result.push(substring);
return result;
}
split("00011122",0,8)
["000", "111", "22"]
To do this dynamically, you can use .split() and .map() methods to make an array from your string then group this array items by value.
This is how should be our code:
const str = "000111111122222223333333444455556666";
var groupArrayByValues = function(arr) {
return arr.reduce(function(a, x) {
(a[x] = a[x] || []).push(x);
return a;
}, []);
};
var arr = str.split("").map(v => +v);
var result = groupArrayByValues(arr);
This will give you an array of separate arrays with similar values each.
Demo:
const str = "000111111122222223333333444455556666";
var groupArrayByValues = function(arr) {
return arr.reduce(function(a, x) {
(a[x] = a[x] || []).push(x);
return a;
}, []);
};
var arr = str.split("").map(v => +v);
var result = groupArrayByValues(arr);
console.log(result);

How to find the most duplicate "values" in javascript array?

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);

Javascript reduce() until sum of values < variable

I am fetching an array of video durations (in seconds) from a JSON file in Javascript, that, to simplify, would look like this:
array = [30, 30, 30]
I would like to add each value to the previous value until a condition is met (the sum being less than a variable x) and then to get both the new value and the index position in the array of the video to play.
For example if x=62 (condition), I would like the first two values in the array to be added (from my understanding reduce() is appropriate here), and the index = 2 (the second video in the array).
I've got the grasp of reduce():
var count = array.reduce(function(prev, curr, index) {
console.log(prev, curr, index);
return prev + curr;
});
But can't seem to get beyond this point.. Thanks
You could use Array#some, which breaks on a condition.
var array = [30, 30, 30],
x = 62,
index,
sum = 0;
array.some(function (a, i) {
index = i;
if (sum + a > x) {
return true;
}
sum += a;
});
console.log(index, sum);
With a compact result and this args
var array = [30, 30, 30],
x = 62,
result = { index: -1, sum: 0 };
array.some(function (a, i) {
this.index = i;
if (this.sum + a > x) {
return true;
}
this.sum += a;
}, result);
console.log(result);
var a = [2,4,5,7,8];
var index;
var result = [0, 1, 2, 3].reduce(function(a, b,i) {
var sum = a+b;
if(sum<11){
index=i;
return sum;
}
}, 2);
console.log(result,index);
What about using a for loop? This is hack-free:
function sumUntil(array, threshold) {
let i
let result = 0
// we loop til the end of the array
// or right before result > threshold
for(i = 0; i < array.length && result+array[i] < threshold; i++) {
result += array[i]
}
return {
index: i - 1, // -1 because it is incremented at the end of the last loop
result
}
}
console.log(
sumUntil( [30, 30, 30], 62 )
)
// {index: 1, result: 60}
bonus: replace let with var and it works on IE5.5
You could do
var limit = 60;
var array = [30,30,30];
var count = array.reduce(function(prev, curr, index) {
var temp = prev.sum + curr;
if (index != -1) {
if (temp > limit) {
prev.index = index;
} else {
prev.sum = temp;
}
}
return prev;
}, {
sum: 0,
index: -1
});
console.log(count);
What about this : https://jsfiddle.net/rtcgpgk2/1/
var count = 0; //starting index
var arrayToCheck = [20, 30, 40, 20, 50]; //array to check
var condition = 100; //condition to be more than
increment(arrayToCheck, count, condition); //call function
function increment(array, index, conditionalValue) {
var total = 0; //total to add to
for (var i = 0; i < index; i++) { //loop through array up to index
total += array[i]; //add value of array at index to total
}
if (total < conditionalValue) { //if condition is not met
count++; //increment index
increment(arrayToCheck, count, condition); //call function
} else { //otherwise
console.log('Index : ', count) //log what index condition is met
}
}
// define the max outside of the reduce
var max = 20;
var hitIndex;
var count = array.reduce(function(prev, curr, index) {
let r = prev + curr;
// if r is less than max keep adding
if (r < max) {
return r
} else {
// if hitIndex is undefined set it to the current index
hitIndex = hitIndex === undefined ? index : hitIndex;
return prev;
}
});
console.log(count, hitIndex);
This will leave you with the index of the first addition that would exceed the max. You could try index - 1 for the first value that did not exceed it.
You can create a small utility method reduceWhile
// Javascript reduceWhile implementation
function reduceWhile(predicate, reducer, initValue, coll) {
return coll.reduce(function(accumulator, val) {
if (!predicate(accumulator, val)) return accumulator;
return reducer(accumulator, val);
}, initValue)
};
function predicate(accumulator, val) {
return val < 6;
}
function reducer(accumulator, val) {
return accumulator += val;
}
var result = reduceWhile(predicate, reducer, 0, [1, 2, 3, 4, 5, 6, 7])
console.log("result", result);

Replace a character many times

in fact, i have to treat a Arabic characters in javascript but i want to show you an example of what i want:
i have this char:
var char = "KASSAB";
i want to get an array of chars by replacing the letter "A" in "1" "2" "3" everytime, so if i have 2 letters "A" in one char, it must be like that:
K**1**SS**1**B,K**1**SS**2**B, K**1**SS**3**B, K**2**SS**1**B, K**2**SS**2**B, K**2**SS**3**B, K**3**SS**1**B, K**3**SS**2**B, K**3**SS**3**B
Any suggestions Please :( ?
This can be done using a recursive function, as follows:
var initialInput = 'KASSAB',
replaceables = ['A', 'a', 'á'],
replacements = ['**1**', '**2**', '**3**'];
function indexOfFirstReplaceable(input) {
var firstIndex = input.length;
for (var i in replaceables) {
var index = input.indexOf(replaceables[i]);
if (index !== -1) firstIndex = Math.min(firstIndex, index);
}
return firstIndex < input.length ? firstIndex : -1;
}
function replaceAllAs(input) {
var index = indexOfFirstReplaceable(input);
if (index === -1) return [input] // Nothing to replace
var outputs = [];
for (var i in replacements) {
var nextInput = input.substr(0, index) + replacements[i] + input.substr(index + 1);
outputs = outputs.concat(replaceAllAs(nextInput));
}
return outputs;
}
console.log(replaceAllAs(initialInput));
will output
["K**1**SS**1**B", "K**1**SS**2**B", "K**1**SS**3**B", "K**2**SS**1**B", "K**2**SS**2**B", "K**2**SS**3**B", "K**3**SS**1**B", "K**3**SS**2**B", "K**3**SS**3**B"]
EDIT:
Or if you want to be more functional, using map and reduce:
var initialInput = 'KASSAB',
replaceables = ['A', 'a', 'á'],
replacements = ['**1**', '**2**', '**3**'];
function indexOfFirstReplaceable(input) {
return replaceables.reduce(function (currentMin, replaceable) {
var index = input.indexOf(replaceable);
if (index === -1 || currentMin === -1) return Math.max(index, currentMin);
else return Math.min(currentMin, index);
}, -1);
}
function replaceAllAs(input) {
var index = indexOfFirstReplaceable(input);
if (index === -1) return [input]; // Nothing to replace
var outputs = replacements.map(function (replacement) {
var nextInput = input.substr(0, index) + replacement + input.substr(index + 1);
return replaceAllAs(nextInput)
});
return [].concat.apply([], outputs);
}
console.log(replaceAllAs(initialInput));
EDIT 2:
To accommodate the overlap of replaceables and replacements you need to specify the fromIndex when using indexOf:
var initialInput = 'KASSAB',
replaceables = ['A', 'a', 'á'],
replacements = ['A', 'a', 'á'];
function indexOfFirstReplaceable(input, fromIndex) {
return replaceables.reduce(function (currentMin, replaceable) {
var index = input.indexOf(replaceable, fromIndex);
if (index === -1 || currentMin === -1) return Math.max(index, currentMin);
else return Math.min(currentMin, index);
}, -1);
}
function replaceAllAs(input, fromIndex) {
var index = indexOfFirstReplaceable(input, fromIndex);
if (index === -1) return [input]; // Nothing to replace
var outputs = replacements.map(function (replacement) {
var nextInput = input.substr(0, index) + replacement + input.substr(index + 1);
return replaceAllAs(nextInput, index + 1);
});
return [].concat.apply([], outputs);
}
console.log(replaceAllAs(initialInput, 0));
will output
["KASSAB", "KASSaB", "KASSáB", "KaSSAB", "KaSSaB", "KaSSáB", "KáSSAB", "KáSSaB", "KáSSáB"]

How to rollup data points using underscore.js?

Say I have an array of 6 numeric data points and want to change it to an array of 3 data points where each point is the sum of a 2 of the points
[1,1,1,1,1,1] ~> [2,2,2]
What is the best way to do this with a library like underscore.js
If you wanted to do it in a generic, functional way, then
function allowIndexes(idx) {
return function(item, index) {
return index % idx;
}
}
function sum() {
return _.reduce(_.toArray(arguments)[0], function(result, current) {
return result + current;
}, 0);
}
var isIndexOdd = allowIndexes(2);
var zipped = _.zip(_.reject(data, isIndexOdd), _.filter(data, isIndexOdd));
console.log(_.map(zipped, sum));
# [ 3, 7, 11 ]
But, this will be no where near the performance of
var result = [];
for (var i = 0; i < data.length; i += 2) {
result.push(data[i] + data[i + 1]);
}
console.log(result);
I found one way. I'll gladly accept a better solution.
values = [1,1,1,1,1,1];
reportingPeriod = 2;
var combined = [];
_.inject( values, function ( total, value, index) {
if ((index + 1) % reportingPeriod === 0) {
combined.push(total + value);
return 0;
} else {
return total + value
}
}, 0);
Using lodash, you could do the following:
let arr = _.fill(Array(6), 1);
let reducer = (sum, num) => sum += num;
arr = _.chain(arr).chunk(2).map(arr => arr.reduce(reducer)).value();

Categories

Resources