How to change swap (change) 0 to 1 in JavaScript array - javascript

Is there some nicer way how to convert 0 to 1 and vice versa in an array in JavaScript than going with for loop and converting it as described here, ie:
var variable1 = [0,1,1,0,0];
var final = []
for (var i=0; i<variable1.length; i++) {
final[i] = 1-variable1[i]
}
//1,0,0,1,1
Something similar to Python's:
[1-i for i in variable1]
# [1,0,0,1,1]
Thanks.

If you can create a new array, I'd use .map instead:
var variable1 = [0,1,1,0,0];
const final = variable1.map(n => 1 - n);
console.log(final);

You can use map to shorten the syntex.
final = variable.map(num => 1^num)
var variable = [0,1,1,0,0];
var final1 = variable.map(num => 1-num) // way one
var final2 = variable.map(num => 1^num) // way two
console.log(final1, final2)

var variable1 = [0,1,1,0,0];
var final = variable1.map(v => v ^ 1);
console.log(final);
It is also looping. but I think this code is more readable.

Related

Convert string to characters then check each character , scribble like behavior

I've already did this using a loop but our instructor said that it can be done with a shorter and simpler method/function. We are not allowed to use for loops or foreach. We can only use es6 related code.
This is my code.
var total = 0
let givenWord = "cabbage"
let pointsTable = new Map([['a',1],['e',1],['i',1],['o',1],['u',1],['l',1],['n',1],['r',1],['s',1],['t',1],
['d',2],['g',2],['b',3],['c',3],['m',3],['p',3],['f',4],['h',4],['v',4],['y',4],['k',5],['j',8],['x',8],['q',10],['z',10]])
for(let [...letters] of givenWord){
for(let [key,value] of pointsTable){
if(letters == key){
total = total + value;
console.log("Total value is " + total)
}
}
}
my problem here is that my loops take up too many lines of code. How do I transform this one into simpler code or using a function/method ? using only ES6?
Ok, I created a sort ES6 way to return the chars in an array and run a check function on them:
const pointsTable = new Map([['a',1],['e',1],['i',1],['o',1],['u',1],['l',1],['n',1],['r',1],['s',1],['t',1],
['d',2],['g',2],['b',3],['c',3],['m',3],['p',3],['f',4],['h',4],['v',4],['y',4],['k',5],['j',8],['x',8],['q',10],['z',10]])
// With ES6
const text= 'abcdefg';
const result = [...text].reduce((acc, cur) => {
return acc + pointsTable.get(cur)
}, 0);
console.log(result);
An other way you could do this is write a while loop and use the String.split(), String.slice() or String.substring() methods to reduce the string to the chars
You can use recursion for this task:
var total = 0
let givenWord = "cabbage"
let pointsTable = new Map([['a',1],['e',1],['i',1],['o',1],['u',1],['l',1],['n',1],['r',1],['s',1],['t',1],
['d',2],['g',2],['b',3],['c',3],['m',3],['p',3],['f',4],['h',4],['v',4],['y',4],['k',5],['j',8],['x',8],['q',10],['z',10]])
const countTotal = (arr, map, points = 0) => {
if(arr.length === 0) return points
points += map.get(arr.splice(0,1)[0])
return countTotal(arr, map, points)
}
console.log(countTotal([...givenWord],pointsTable))
Using the split method it will separate the text into the individual letters. Then you can use the map method to iterate through each of those letters and do a check within that.
const test = 'abcdefg'
let total = 0;
let pointsTable = new Map([['a',1],['e',1],['i',1],['o',1],['u',1],['l',1],
['n',1],['r',1],['s',1],['t',1],
['d',2],['g',2],['b',3],['c',3],['m',3],['p',3],['f',4],['h',4],['v',4],
['y',4],['k',5],['j',8],['x',8],['q',10],['z',10]])
test.split('').map(function(letter){
let value = pointsTable.get(letter)
total += value;
});
Here's the shortest way I can think of :
var total = 0
let givenWord = "cabbage"
let pointsTable = new Map([['a',1],['e',1],['i',1],['o',1],['u',1],['l',1],['n',1],['r',1],['s',1],['t',1],
['d',2],['g',2],['b',3],['c',3],['m',3],['p',3],['f',4],['h',4],['v',4],['y',4],['k',5],['j',8],['x',8],['q',10],['z',10]])
let total = givenWord.split``.reduce((a,l)=>a+pointsTable.get(l),0)
console.log("Total value is " + total)
details :
let total = // assign to total
givenWord // the givenword
.split`` // splited to get an array of characters
.reduce( // call reduce on the array
(a, l) => { // first arg of reduce is a function
// called for each elements of the array
// arguments are the accumulator, the letter
a + pointsTable.get(l) // add the letter score to the accumulator
},
0 // set default value of accumulator (2nd arg of reduce)
)
fn`` documentation (look at section tagged template),
reduce documentation

For loop inside a method using Vuejs

I have a method in Vuejs which updates a set of variables based on a selection.
methods: {
updateChart(){
this.chart1.series[1].data = [this.$store.state.selectedcities[0].value[1]];
this.chart1.series[2].data = [this.$store.state.selectedcities[0].value[2]];
this.chart1.series[3].data = [this.$store.state.selectedcities[0].value[3]];
this.chart1.series[5].data = [this.$store.state.selectedcities[0].value[5]];
this.chart1.series[7].data = [this.$store.state.selectedcities[0].value[7]];
this.chart1.series[8].data = [this.$store.state.selectedcities[0].value[8]];
this.chart1.series[9].data = [this.$store.state.selectedcities[0].value[9]];
this.chart1.series[11].data = [this.$store.state.selectedcities[0].value[11]];
this.chart1.series[12].data = [this.$store.state.selectedcities[0].value[12]];
this.chart1.series[13].data = [this.$store.state.selectedcities[0].value[13]];
this.chart1.series[14].data = [this.$store.state.selectedcities[0].value[14]];
this.chart1.series[16].data = [this.$store.state.selectedcities[0].value[16]];
this.chart1.series[17].data = [this.$store.state.selectedcities[0].value[17]];
this.chart1.series[18].data = [this.$store.state.selectedcities[0].value[18]];
this.chart1.series[20].data = [this.$store.state.selectedcities[0].value[20]];
this.chart1.series[21].data = [this.$store.state.selectedcities[0].value[21]];
this.chart1.series[22].data = [this.$store.state.selectedcities[0].value[22]];
}
The problem is that it looks rather verbose, so I wonder if I can run a for loop there that iterates through those numbers. The thing is that the numbers aren't sequenced. I mean the series runs as {1,2,3,5,7,8,9,11,12,13,14,16,17,18,20,21,22}.
In the end what I'm searching for is something that looks like this:
methods:{
updateChart(){
var n = {1,2,3,5,7,8,9,11,12,13,14,16,17,18,20,21,22}
for(i in n){
this.chart1.series[i].data = [this.$store.state.selectedcities[0].value[i]];
}
}
}
I'm not really sure how to do it as I'm quite new to javascript.
EDIT:
Is it possible to add a nested foreach with this method?
For example:
var k = [1,3,6]
var n = [1,2,3,5,7,8,9,11,12,13,14,16,17,18,20,21,22]
n.forEach(i=>{
this.chart[k].series[i].data = [this.$store.state.selectedcities[k].value[i]];
})
Note that k was added to the formula and that n is child of k. So for each k it should run the series of n.
n should be an array and loop through it using forEach method like :
var n = [1,2,3,5,7,8,9,11,12,13,14,16,17,18,20,21,22]
n.forEach(i=>{
this.chart1.series[i].data = [this.$store.state.selectedcities[0].value[i]];
})
ُEDIT
var m = [1,3,6]
m.forEach(k=>{
n.forEach(i=>{
this.chart[k].series[i].data =
[this.$store.state.selectedcities[k].value[i]];
})
})
You could use foreach.
updateChart() {
var n = [1,2,3,5,7,8,9,11,12,13,14,16,17,18,20,21,22];
n.forEach(number => {
this.chart1.series[number].data = [this.$store.state.selectedcities[0].value[number]];
});
}

How to split String, convert to Numbers and Sum

I have a function that I have modified to get a string (which consists of zeros and ones only).
The string (timesheetcoldata):
100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000
The string items (the numbers one and zero) will change every time the function is run.
It will always be the same length.
I have made the string above easier to see what I am trying to achieve.
I want to return the first character and then every 24th character (as in the variable colsCount in the function).
so, in the example above, it would return something like: 111111
I then want to convert these characters to numbers (something like [1, 1, 1, 1, 1, 1]).
I then want to sum these number together (so it would return, in the example: 6).
I then want to check if the returned number matches the variable: rowsCount
or true if it does, false if it does not.
My function:
$("#J_timingSubmit").click(function(ev){
var sheetStates = sheet.getSheetStates();
var rowsCount = 6;
var colsCount = 24;
var timesheetrowsdata = "";
var timesheetcoldata = "";
for(var row= 0, rowStates=[]; row<rowsCount; ++row){
rowStates = sheetStates[row];
timesheetrowsdata += rowStates+(row==rowsCount-1?'':',');
}
timesheetcoldata = timesheetrowsdata.replace(/,/g, '');
console.log(timesheetcoldata);
});
Thank you very much to both Rajesh and MauriceNino (and all other contributers).
With their code I was able to come up with the following working function:
$("#J_timingSubmit").click(function(ev){
var sheetStates = sheet.getSheetStates();
var rowsCount = 6;
var timesheetrowsdata = "";
var timesheetcoldata = "";
for(var row= 0, rowStates=[]; row<rowsCount; ++row){
rowStates = sheetStates[row];
timesheetrowsdata += rowStates+(row==rowsCount-1?'':',');
}
timesheetcoldata = timesheetrowsdata.replace(/,/g, '');
var count = 0;
var list = [];
for(var i = 0; i< timesheetcoldata.length; i+=24) {
const num1 = Number(timesheetcoldata.charAt(i));
list.push(num1);
count += num1;
}
let isSameAsRowsCount = count == rowsCount;
console.log('Is Same? ', isSameAsRowsCount);
});
You can always rely on traditional for for such action. Using functional operations can be more readable but will be more time consuming(though not by much).
You can try this simple algo:
Create a list that will hold all numbers and a count variable to hold sum.
Loop over string. As string is fixed, you can set the increment factor to the count(24).
Convert the character at given index and save it in a variable.
Push this variable in list and also compute sum at every interval.
At the end of this loop, you have both values.
var string = '100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000';
var count = 0;
var list = [];
for(var i = 0; i< string.length; i+=24) {
const num1 = Number(string.charAt(i));
list.push(num1);
count += num1;
}
console.log(list, count)
Here is a step by step explanation, on what to do.
Use match() to get every nth char
Use map() to convert your array elements
Use reduce() to sum your array elements
Everything needed to say is included in code comments:
const testData = '100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000';
// Step 1) Create array of numbers from string
const dataArr = testData.match(/.{1,24}/g) // Split on every 24th char
.map(s => Number(s[0])) // Only take the first char as a Number
console.log(dataArr);
// Step 2) Sum array Numbers
let dataSum = dataArr.reduce((a, b) => a + b); // Add up all numbers
console.log(dataSum);
// Step 3) Compare your variables
let rowsCount = 123; // Your Test variable
let isSameAsRowsCount = dataSum == rowsCount;
console.log('Is Same? ', isSameAsRowsCount);
As #Jaromanda mentioned, you can use the following to done this.
const string = '100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000';
const value = string.split('').filter((e,i)=> !(i%24)).reduce((acc,cur)=> acc+ (+cur), 0);
console.log(value);

How to split and change to different format in javascript

I am new for javascript, I have a one long string i want to split after 3rd commas and change diffferent format. If you are not understand my issues. Please see below example
My string:
var test= "10,Idly(3 Pcs),200,10,Ghee Podi Idly,300";
I want output like this:(Each item should be in next line)
Idly(3 Pcs) - 10 = 200
Ghee Podi Idly - 10 = 300
How to change like this using JavaScript?
Just copy and paste it. Function is more dynamic.
Example Data
var testData = "10,Idly(3 Pcs),200,10,Ghee Podi Idly,300";
Function
function writeData(data){
data = data.split(',');
var tempLine='';
for(var i=0; i<data.length/3; i++) {
tempLine += data[i*3+1] + ' - ' + data[i*3] + ' = ' + data[i*3+2] + '\n';
}
alert(tempLine);
return tempLine;
}
Usage
writeData(testData);
Use split method to transform the string in a array and chunk from lodash or underscore to separate the array in parts of 3.
// A custom chunk method from here -> http://stackoverflow.com/questions/8495687/split-array-into-chunks
Object.defineProperty(Array.prototype, 'chunk_inefficient', {
value: function(chunkSize) {
var array=this;
return [].concat.apply([],
array.map(function(elem,i) {
return i%chunkSize ? [] : [array.slice(i,i+chunkSize)];
})
);
}
});
var test= "10,Idly(3 Pcs),200,10,Ghee Podi Idly,300";
var arr = test.split(',');
var arr = arr.chunk_inefficient(3);
arr.forEach(function (item) {
console.log(item[1]+' - '+item[0]+' = '+item[2]);
});
You can use split to split the string on every comma. The next step is to iterate over the elements, put the current element into a buffer and flush the buffer if it's size is three. So it's something like:
var tokens = test.split(",");
var buffer = [];
for (var i = 0; i < tokens.length; i++) {
buffer.push(tokens[i]);
if (buffer.length==3) {
// process buffer here
buffer = [];
}
}
If you have fix this string you can use it otherwise validate string.
var test= "10,Idly(3 Pcs),200,10,Ghee Podi Idly,300";
var test2= test.split(",");
var temp_Str= test2[1]+' - '+test2[0]+' = '+test2[2]+'\n';
temp_Str+= test2[4]+'-'+test2[3]+' = '+test2[5];
alert(temp_Str);

Json Joining as in SQL

i have json objects like
{"COLORS":[[1,red],[2,yellow],[3,orange]]}
{"FRUITS":[[1,apple,1],[2,banana,2],[3,orange,3], [4,grenade,1], [5,apple,2]]}
i need to make them like:
{"FRUITS":[[1,apple,red],[2,banana,yellow],[3,orange,orange], [4,grenade,red], [5,apple,yellow]]}
I think a simple nested loop is the simplest way to solve this.
As far as i know there is no "json join" feature in javascript.
Try this:
var colors = {"COLORS":[[1,"red"],[2,"yellow"],[3,"orange"]]};
var fruits = {"FRUITS":[[1,"apple",1],[2,"banana",2],[3,"orange",3], [4,"grenade",1], [5,"apple",2]]};
console.log(fruits);
for (var i = 0; i < fruits.FRUITS.length; i++) {
var temp = fruits.FRUITS[i];
for (var j = 0; j < colors.COLORS.length; j++) {
if (colors.COLORS[j][0] === temp[2]) {
temp[2] = colors.COLORS[j][1];
break;
}
};
fruits.FRUITS[i] = temp;
};
console.log(fruits);
You could even use jQuery.each() to help you iterating over array. And also use Array.prototype.filter() to find a color related to id in fruits array.
var colors = {"COLORS":[[1,"red"],[2,"yellow"],[3,"orange"]]};
var fruits = {"FRUITS":[[1,"apple",1],[2,"banana",2],[3,"orange",3], [4,"grenade",1], [5,"apple",2]]}
var f = fruits.FRUITS;
$.each(f, function(i, fruitItem) {
var colorItem = colors.COLORS.filter(function(color) {
return color[0] == fruitItem[2]
});
fruitItem[2] = colorItem[0][1]
});
console.log(fruits)
Another similar method to finnmich, using filter() instead of a nested loop.
This builds a new array and ignores entries which do not have matching ids, like a sql join:
var c = {"COLORS":[[1,"red"],[2,"yellow"],[3,"orange"]]};
var f = {"FRUITS":[[1,"apple",1],[2,"banana",2],[3,"orange",3], [4,"grenade",1], [5,"apple",2]]};
var result = [];
for(var i = 0; i < f.FRUITS.length; i++)
{
var entry = f.FRUITS[i];
var id = entry[2];
var color = c.COLORS.filter(function(v) {
return v[0] == id;
});
if(color.length > 0) {
result.push([entry[0], entry[1], color[0][1]]);
}
}
console.dir(result);
Here is a simple solution using jq. It assumes that $colors and $fruits contain the JSON values for 'colors' and 'fruits' respectively:
$colors.COLORS | map( {(.[0]|tostring): .[1] } ) | add as $dict
| $fruits
| .FRUITS |= map( (.[2]) |= $dict[tostring] )
The example below shows how to set $coloars and $fruits.
If your jq has INDEX/1, the first line above could be shortened to:
$colors.COLORS | INDEX(.[0]) | map_values(.[1]) as $dict
Explanation
The first line produces a dictionary ($dict), which is then used to make the translation.
Example
Assuming colors.json and fruits.json hold valid JSON values corresponding to the example give in the question, and that program.jq holds the above jq program, the invocation:
jq -n --argfile colors colors.json --argfile fruits fruits.json -f program.jq
yields:
{"FRUITS":[[1,"apple","red"],[2,"banana","yellow"],[3,"orange","orange"],[4,"grenade","red"],[5,"apple","yellow"]]}

Categories