How to change a range of array with one value Javascript? - javascript

I have an array like below let's say
var myArray = ["1", "", "", "2","3","","","8"];
And I want to fill each " " value with previous not null value
According to that expectation should be like below
var myArray = ["1", "2", "2", "2","3","8","8","8"];
Here what I tried but didn't work
var myArray = ["1", "", "", "2","3","","","8"];
function myFunction() {
let currentEl=myArray [0];
let prevIndex=0;
fruits.map((e,a)=>{
if(e!="" && myArray[a-1]==""){
currentEl=e;
let interval=arrayGenerate(a-currentIndex-1,currentEl);
fruits.splice(currentIndex-1, currentEl+1, interval);
currentIndex=a;
}
})
}
function arrayGenerate(iteration,value){
let arr=[];
for(var i=0;i<iteration;i++){
arr.push(value);
}
return arr;
}
console.log(myArray)

You could map the new values and find the missing following value.
var array = ["1", "", "", "2", "3", "", "", "8"],
result = array.map((v, i, a) => v || a.find((w, j) => j > i && w));
console.log(result);
A solution with the same array, by looping from the end and storing the last value.
var array = ["1", "", "", "2", "3", "", "", "8"],
i = array.length,
value;
while (i--) {
if (array[i]) value = array[i];
else array[i] = value;
}
console.log(array);

I have done it like this. I loop over and awlays check the next element if its falsy and not the last element.
var myArray = ["1", "", "", "2","3","","","8"];
function fillArr(arr){
for(let i = arr.length - 1; i >= 0; i--){
if(!arr[i - 1] && i != arr.length){
arr[i - 1] = arr[i];
}
}
return arr;
}
let result = fillArr(myArray);
console.log(result);

You can make use of a stack array to stack indices of null items and then unstack them whenever you encounter a non null item in myArray. (stack is not a reserved keyword so you can call it anything) :
var stack = []
for(var i = 0; i < myArray.length; i++){
if(myArray[i] === "")
stack.push(i);
else if(stack.length !== 0){
for(var j = stack.length - 1 ; j > =0; j--){
myArray[stack[j]] = myArray[i];
stack.splice(j,1);
}
}
}

It's interesting how many different ways this can be done. Just another slightly ugly way to do the same thing:
const fill = (arr, lastVal) => (
arr.reverse()
.map(el => el.length > 0 ? lastVal = el : lastVal)
.reverse()
);
console.log(fill(["1", "", "", "2","3","","","8"]));

Related

How to get max number from Array<String> in TS orJS

I'd like to create like this function in JS or TS but I couldn't.
Please teach me ...!
It is better if its function is made by functional-programming.
・Input type:Array(String)
・Output type:string or undefined
ex
Input
Result
["","0","3"]
"3"
["","",""]
undefined
["0","0","0"]
"0"
["1","3","2"]
"3"
Filter out all non-number elements from array.
Convert all string-number to Number type.
Use Math.max to get the largest value from array.
function getMaxValue(input) {
if (input.length) {
return Math.max.apply(null, input);
}
}
function sanitize(input) {
return input.filter(i => {
if (i === "" || i === null) {
return false;
}
return !isNaN(i);
}).map(i => Number(i));
}
let input1 = ["", "", "0"];
let input2 = [1, 3, 5];
let input3 = ["1", "", "5"];
let input4 = ["", "", ""];
let input5 = [undefined, null, "", "", "", "10"];
console.log(getMaxValue(sanitize(input1)));
console.log(getMaxValue(sanitize(input2)));
console.log(getMaxValue(sanitize(input3)));
console.log(getMaxValue(sanitize(input4)));
console.log(getMaxValue(sanitize(input5)));
You can try this.
const findMaximuminArray = (arr) => {
let max = arr[0];
for (let i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
if(max === "") return undefined;
return max;
}
You are using strings in your example, such as "1", but all of them contain digits actually, so I'm not sure what you're really trying to do.
However, here's a function that generates the results you want using lodash/fp:
_.compose(x => x ? x : undefined, _.max)
Whatever array argument you pass to it, it will get the maximum value and then convert it to undefined if it is falsy, as is the case for the empty string.
Here's the results generated for your input:
const fun = _.compose(x => x ? x : undefined, _.max);
const input = [["","0","3"],["","",""],["0","0","0"],["1","3","2"]]
_.forEach(x => console.log(fun(x)), input);
<script src="https://cdn.jsdelivr.net/g/lodash#4(lodash.min.js+lodash.fp.min.js)"></script>

How to count the occurrence of each key within an array of objects?

Say I have an array of objects like so:
[{"taco":"","burrito":"","scone":"","beans":"true"},
{"taco":"true","burrito":"","scone":"true","beans":""},
{"taco":"true","burrito":"","scone":"","beans":""},
{"taco":"true","burrito":"","scone":"","beans":"true"}]
I need to count the occurrence of each element and return in it in an array
[3, 0, 1, 2]
any ideas would be appreciated, thanks!
I have attempted
var a = datasets.reduce(function (item, index) {
if (typeof item[index] == 'undefined') {
item[index] = 1;
} else {
item[index] += 1;
}
return item;
}, {});
could not get anything like that to work so i attempted converting it to json and then removing any key: value pairs with no value then counting remaining ones but have had no success with that either
function tableToJson(table) {
var data = [];
var headers = [];
for (var i=0; i < table[0].rows[0].cells.length; i++) {
headers[i] = table[0].rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi,'');
}
for (var i=1; i< table[0].rows.length; i++) {
var tableRow = table[0].rows[i];
var rowData = {};
for (var j=0; j<tableRow.cells.length; j++) {
rowData[ headers[j] ] = tableRow.cells[j].innerHTML;
}
data.push(rowData);
}
return data
}
function removeEmpty(jsonObj) {
var newObj = Object.getOwnPropertyNames(jsonObj);
for (var i = 0; i < newObj.length; i++) {
var value = newObj[i];
if (jsonObj[value] === null || jsonObj[value] === undefined) {
delete jsonObj[value];
}
}
}
You can try this
You can do it with reduce().
What i have done is first i check is the object property of current element if it is already in output object. If it's present than i check the value of current element property. if it is true than i increment the property of output object by 1.
If the object property of current element is not available in output than i check for the value of current element property. if it is true i assign output object property with value 1. if false i assign output object property with 0.
let obj = [{"taco":"","burrito":"","scone":"","beans":"true"},
{"taco":"true","burrito":"","scone":"true","beans":""},
{"taco":"true","burrito":"","scone":"","beans":""},
{"taco":"true","burrito":"","scone":"","beans":"true"}]
let op = obj.reduce((output,current)=>{
for(let key in current){
if( output[key] ){
if( current[key] ) output[key]+=1;
} else {
if( current[key] ){
output[key] = 1;
} else{
output[key] = 0;
}
}
}
return output;
},{})
console.log(op);
Try this:
var data = [{
taco: "",
burrito: "",
scone: "",
beans: "true"
},
{
taco: "true",
burrito: "",
scone: "true",
beans: ""
},
{
taco: "",
burrito, "true",
scone: "",
beans: "",
}, {
taco: "true",
burrito: "",
scone: "",
beans: "true"
}]
var total = [0, 0, 0, 0];
data.forEach(function(obj) {
if (obj.taco) {
total[0]++;
}
if (burrito) {
total[1]++;
}
if (obj.scone) {
total[2]++;
}
if (obj.beans) {
total[3]++;
}
})
console.log(total)
You can loop through the array and then loop through the keys of each object. Then increment the key of the countObject if it already exists or assign it zero.
This is dynamic. Even if one of the object has an extra key, it will count them. This doesn't expect all the items of array to have the same keys.
var array = [
{"taco":"","burrito":"","scone":"","beans":"true"},
{"taco":"true","burrito":"","scone":"true","beans":""},
{"taco":"true","burrito":"","scone":"","beans":""},
{"taco":"true","burrito":"","scone":"","beans":"true"}
]
var countObject = {};
array.forEach(item => {
Object.keys(item).forEach(key => {
if (item[key] === "true")
countObject[key] = countObject[key] + 1 || 1
else
countObject[key] = countObject[key] || 0
})
})
console.log(countObject); // get the key and count pair
console.log(Object.values(countObject)); // get the counts in an array

JavaScript: Compare two arrays and return index of matches

I have the following code.
function findMatch(array_1_small, array2_large) {
var ary = new Array();
for(i = 0;i < array2_large.length; i++)
{
for(z = 0; z < array_1_small.length; z++)
{
if(array2_large[i] == array_1_small[z])
{
var idx = array2_large.indexOf(array2_large[i]);
ary.push(idx);
}
}
}
return ary;
}
That takes the following arrays.
var all_SMS_TO = ["0861932936", "0871355066", "0874132026", "0872908445", "0874132026"];
var all_FORM_NUMBERS = ["", "", "", "", "", "", "0871355066",""];
The sole purpose is to find a match and return the index of the match on the 'all_form_numbers array.
On calling the code
var a = findMatch(all_SMS_TO, all_FORM_NUMBERS);
console.log("Match Found " + a);
I get the following output.
Match Found: 6
Which is correct, however when I alter the all_form_Numbers array to
var all_FORM_NUMBERS = ["", "0871355066", "", "", "", "", "0871355066",""];
I get The following output.
Match Found: 1,1
Could somebody help me with this so it should output;
Match Found 1, 6.
Thanks.
try this:
function findMatch(array_1_small, array2_large) {
var ary = new Array();
for(i = 0;i < array2_large.length; i++)
{
for(z = 0; z < array_1_small.length; z++)
{
if(array2_large[i] == array_1_small[z])
{
ary.push(i);
}
}
}
return ary;
}
When you do
var idx = array2_large.indexOf(array2_large[i]);
you are searching for the index of the value 0871355066 in the array array2_large twice and as per the definition of indexOf it will returns the position of the first occurrence of a specified value.
This is why you are getting index value 1 twice since its the index of first occurrence.
For solution Just push the variable i value into the array ary. Which is already the index value of array2_large in the loop.
function findMatch(array_1_small, array2_large) {
var ary = new Array();
for(i = 0;i < array2_large.length; i++)
{
for(z = 0; z < array_1_small.length; z++)
{
if(array2_large[i] == array_1_small[z])
{
ary.push(i);
}
}
}
return ary;
}
var all_SMS_TO = ["0861932936", "0871355066", "0874132026", "0872908445", "0874132026"];
//var all_FORM_NUMBERS = ["", "", "", "", "", "", "0871355066",""];
var all_FORM_NUMBERS = ["", "0871355066", "", "", "", "", "0871355066",""];
var a = findMatch(all_SMS_TO, all_FORM_NUMBERS);
console.log("Match Found " + a);
You just need to push the index i here is the fixed code (you can also declare an array as var res = [];
function findMatch(arraySmall, arrayLarge) {
var res = []
for (var i = 0; i < arrayLarge.length; i++) {
for (var j = 0; j < arraySmall.length; j++) {
if (arrayLarge[i] === arraySmall[j]) {
res.push(i);
}
}
}
return res;
}
It is possible to solve this on O(n+m) runtime complexity by creating a lookup table of positions first. Then you map each element from the first array to all positions and collect these indices in a Set to only leave unique values.
Try this:
var all_SMS_TO = ["0861932936", "0871355066", "0874132026", "0872908445", "0874132026"];
var all_FORM_NUMBERS = ["", "0871355066", "", "", "", "", "0871355066",""];
function findMatch(array_1_small, array2_large) {
var positions = Array.from(array2_large.entries()).reduce((acc, t) => {
var index = t[0]
var element = t[1]
if (!acc.hasOwnProperty(element)) {
acc[element] = []
}
acc[element].push(index)
return acc
}, {})
var result = new Set()
array_1_small.forEach(x => {
if (positions[x] === undefined) {
return
}
positions[x].forEach(index => result.add(index))
})
return Array.from(result)
}
console.log("Match found: " + findMatch(all_SMS_TO, all_FORM_NUMBERS))

Comparing two arrays and push in another array wrong position element

I got two arrays, both type string :
var correctAnswers = ["0", "1", "2", "3", "4", "5"];
and second :
var finalArray = ["0", "1", "4", "3", "5", "2"];
I would like to compare them and and if not match second with first to extract elements and push them in another array, like this :
finalArray = ["0", "1", "3"];
var toChange = ["4", "5", "2"];
You could use jQuery map method too:
var toChange = $.map(finalArray, function(v, k){
return correctAnswers[k] !== v ? v: null;
});
finalArray = $.map(finalArray, function(v, k){
return correctAnswers[k] === v ? v: null;
});
DEMO
Or using array.prototype.filter():
var toChange = finalArray.filter(function(v, k){
return correctAnswers[k] !== v;
});
finalArray = finalArray.filter(function(v, k){
return correctAnswers[k] === v;
});
filter DEMO
var toChange = [];
for (var i = finalArray.length - 1; i >= 0; i--) {
if (finalArray[i] !== correctAnswers[i]) {
toChange.push(finalArray[i]);
finalArray.splice(i, 1);
}
}
The key to this is iterating down from the length to 0, rather than up from 0 to the length as usual. This is because splice changes the indexes of all the elements after the element being removed, so normal iteration would skip an element after each splice.
This will do it:
http://jsfiddle.net/XiozZe/NkM6s/
var correctAnswers = ["0", "1", "2", "3", "4", "5"];
var finalArray = ["0", "1", "4", "3", "5", "2"];
var correctFinal = [];
var toChange = [];
for(var i = 0; i < correctAnswers.length; i++){
if(correctAnswers[i] === finalArray[i]){
correctFinal[correctFinal.length] = finalArray[i];
}
else{
toChange[toChange.length] = finalArray[i];
}
}
First you've got to define your variables
// Define your variables
var correctAnswers = ["0", "1", "2", "3", "4", "5"];
var answers = ["0", "1", "4", "3", "5", "2"];
var finalArray = [];
var toChange = [];
Then you create a loop, which loops over the Answers array.
// comparing them could be done with a simple loop
for (var i = 0; i<answers.length; i++) {
if (correctAnswers[i] == answers[i]) { //if they're equal, push the value into the final array
finalArray.push(answers[i]);
} else { // if not, push them into the toChange array
toChange.push(answers[i]);
}
}
This will give you toChange = [0, 1, 3]
If you want toChange = [0, 1] you've got to change it to
toChange = answers.slice(0);
for (var i = 0; i<correctAnswers.length; i++) {
if (correctAnswers[i] == Answers[i]) { //if they're equal, push the value into the final array and remove the first value from the toChange array
finalArray.push(Answers[i]);
toChange.shift();
} else { // if not, break
break;
}
}
Fiddle

.splice() doesn't shorten my array completly

I have an array with Strings, if there is nothing written in the String I want to remove it from the array with .splice().
Somehow it does not get all empty entries. If there are 2 empty entries in the beginning, it only gets one.
Here is my fiddle and code:
stringArray = ["", "", "Banana"];
console.log('before stringArray.length: ' + stringArray.length);
for (var i = 0; i < stringArray.length; i++) {
if (stringArray[i] === "") {
stringArray.splice(i, 1);
if (i > 0) i--;
}
}
console.log('after stringArray.length: ' + stringArray.length);
You have to loop backwards, because every time you splice, the length and indexes change:
for (var i = stringArray.length-1; i>=0; i--) {
if(stringArray[i] === ""){
stringArray.splice(i, 1);
}
}
Alternate solution with Array.prototype.filter (documentation page provides a shim for old browsers that won't support this method):
stringArray = [ "","","Banana"];
var a = stringArray.filter(function(item) {
return item !== '';
});
console.log(a);
Another option, of course with looping backwards, is with a while loop:
var stringArray = ["", "", "", "Apple", "", "", "Banana", "", "", ""];
var i = stringArray.length;
while (i-- && (stringArray[i] !== "" || stringArray.splice(i, 1)));
console.log(stringArray); // ["Apple", "Banana"]
DEMO: http://jsfiddle.net/VEmAV/

Categories

Resources