I want to check that two arrays contain the same elements (not deep equals) in the same order.
var a = { id: 1 }
var b = { id: 2 }
var c = { id: 3 }
var arr = [a, b, c]
expect(arr).to.______([a, b, c]) // true
expect(arr).to.______([a, c, b]) // false: different order
expect(arr).to.______([a, b]) // false: missing element
expect(arr).to.______([a, b, c, { id: 4 }]) // false: extra element
expect(arr).to.______([a, b, { id: 3 }]) // false: different object reference
Of course I can write
assert.strictEqual(arr.length, expected.length, "length");
for (let q = 0; q < arr.length; ++q) assert.strictEqual(arr[q], expected[q], `[${q}]`);
But I think there should be some method for that already.
You could use .ordered in conjunction with .members, like this:
By default, members are compared using strict (===) equality. Add .deep earlier in the chain to use deep equality instead.
const expect = chai.expect;
const a = 1;
const b = 2;
const c = 3;
const input = [a, b, c];
expect(input).to.have.ordered.members([a, b, c]);
expect(input).to.not.have.ordered.members([b, a, c]);
expect(input).to.not.have.ordered.members([a, c, b]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.2.0/chai.min.js"></script>
Related
Is it possible do not include an argument conditionally when calling a function?
Exemple
Here is a snippet of what behavior I am wanting:
const a=1;
const b="spam";
console.log( a, b!="spam"?b:undefined ); // I would like to ignore b when b=="spam"
// expected output: "1"
// actual output: "1 undefined"
Testings
Here is a snippet representing a logging of every value I have tested so far:
Value
const a="a";
const b=0;
const c=NaN;
const d=null;
const e=undefined;
const f=void 0;
const g="g";
console.log(a,b,c,d,e,f,g);
// expected output: a 0 NaN null g
// actual output: a 0 NaN null undefined undefined g
Filter
const variable = null;
let test = [variable].filter(f => f != null).join();
console.log("start");
console.log(); // no output
console.log(test); // output: "" (type: string)
console.log(typeof test); // output: "string"
console.log(); // no output
console.log("end");
Filter & Apply
const variable=null;
let test = [variable].filter(f => f != variable);
console.log("start");
console.log(test); // output: "(0) []"
console.log.apply(console, test); // no output
console.log.apply(console, null); // no output
console.log("end");
Workaround
That:
const a=1;
const b="spam"
b!="spam"?console.log(a,b):console.log(a);
works, but it is not ignoring an argument at call, it rather test the variable before to then not include it as an argument
Build an array, filter it of unnecessary values, then use the spread syntax ..., like this
const a = "a";
const b = 0;
const c = NaN;
const d = null;
const e = undefined;
const f = void 0;
const g = "g";
console.log(...[a, b, c, d, e, f, g].filter((x) => x !== undefined));
If you want, you can declare as well your console.logDefined function, like this:
console.logDefined = function () {
console.log(...Array.from(arguments).filter((x) => x !== undefined));
};
const [a, b, c, d, e, f, g] = ["a", 0, NaN, null, undefined, void 0, "g"];
console.log( "console.log array >>", a, b, c, d, e, f, g);
console.logDefined("console.logDefined array >>", a, b, c, d, e, f, g);
I an trying to destructure two object with the same property names but only the names of the first set are observed.
let a, b,
({ a,b } = myObject1);
({ a,b } = myObject2);
ie; only the values for myObject1 are in the console.log()
Does anyone know how to destructure properties of the same name from different objects ? I do not want to manually assign each variable.
I had tried
let a, b,
({ a,b } = myObject1);
({ a : test1,b: test2 } = myObject2)
console.log(test1)
and
let a, b,
{ a,b } = myObject1;
{ a : test1,b: test2 } = myObject2
console.log(test1)
But test1 is undefined
let { a: a1, b: b1 } = myObject1;
let { a: a2, b: b2 } = myObject2;
Will create variables a1, b1, a2, b2 from your 2 objects.
Assign name to variables.
let a, b,
({ a,b } = myObject1);
({ a: A,b:B } = myObject2);
If you have more objects with the same structure, you could take a function which returns an array of wanted properties.
const getProps = ({ a, b }) => [a, b];
let [a, b] = getProps(myObject1),
[c, d] = getProps(myObject2);
function partialize(){
}
function calculation(a,b,c){
console.log(a*b/c);
return a*b/c;
}
var a = 10, b= 20, c= 5;
var partialize1 = partialize(calculation, a);
partialize1(b,c)
var partialize2 = partialize(calculation, a, b);
partialize2(c)
var partialize3 = partialize(calculation, a, b, c);
partialize3()
I need to write partialize function which give same output in all three condition.
I tried like that it work .but i used spread operator .can we do this without spread operator ?
function partialize(fn,...a) {
console.log(...a);
return function (...b) {
console.log(...b);
fn(...a,...b);
}
}
function calculation(a, b, c) {
console.log(a * b / c);
return a * b / c;
}
var a = 10, b = 20, c = 5;
var partialize1 = partialize(calculation, a);
partialize1(b, c)
var partialize2 = partialize(calculation, a, b);
partialize2(c)
var partialize3 = partialize(calculation, a, b, c);
partialize3()
can we do the same thing without spread operator ?
You can save the initial arguments that were passed and return a function that can be called with the rest of the arguments, then calling the original function with apply:
function partialize(fn) {
const initialArguments = Array.from(arguments).slice(1);
return function() {
const finalArguments = Array.from(arguments);
fn.apply(null, initialArguments.concat(finalArguments));
}
}
function calculation(a, b, c) {
console.log(a * b / c);
return a * b / c;
}
var a = 10,
b = 20,
c = 5;
var partialize1 = partialize(calculation, a);
partialize1(b, c)
var partialize2 = partialize(calculation, a, b);
partialize2(c)
var partialize3 = partialize(calculation, a, b, c);
partialize3()
If your code is currently working as is but you'd like to change it to not use the spread operator, you can use the arguments object instead.
arguments object:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
Also check out this stackoverflow question for some example code working with the arguments object if helpful. How can I convert the "arguments" object to an array in JavaScript?
user944513, to simulate an overload of methods in javascript, yo can use the arguments object, which comes by default in the functions. To explain you better, i've written a block of code. Hope this can help you:
function suma(a = 0){
let resultado = 0;
console.log(arguments.length);
for(let i = 0; i < arguments.length; i++)
{
if(typeof(arguments[i] == "number")){
resultado += arguments[i];
}
}
}
suma(1,2,3,4); // 10
suma(1,2) // 3
There is a well known method to swap 2 numeric variables without using a 3rd variable with simple arithmetic operations.
a = 3;
b = 5;
b += a;
a = b - a;
b -= a;
console.log(a); //5
console.log(b); //3
No mystery here. But I need to swap two variables that are objects and I have no idea how to tackle this.
The objects are very complex with properties of different data types and methods. Here is an example for simplification:
a = {
label: "xxxxxxx",
active: false,
doThatThang: function(val) {
//some code
}
};
I'm currently using a 3rd variable to perform the swap but the objects are really big and it's messing with the animation where the variables are swapping values.
Use ES6 array destructuring.
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a);
console.log(b);
Ref: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
Try ES6 Array Destructing assignment.
DEMO
let a = {
label: "111111",
active: false,
doThatThang: function(val) {
//some code
}
};
let b = {
label: "222222",
active: false,
doThatThang: function(val) {
//some code
}
};
console.log("Before swap");
console.log(a);
console.log(b);
[a, b] = [b, a];
console.log("After swap");
console.log(a);
console.log(b);
var a=1,
b=2,
output=document.getElementById('output');
output.innerHTML="<p>Original: "+a+", "+b+"</p>";
b = [a, a = b][0];
output.innerHTML+="<p>Swapped: "+a+", "+b+"</p>";
<div id="output"></div>
Use a third variable when swapping objects. There is no simpler way to do it in ES5.
var first = {property: 'value'}
var second = {more: 'stuff'}
console.log('Before')
console.log(first)
console.log(second)
var temp = first
first = second
second = temp
console.log('After')
console.log(first)
console.log(second)
Let Say a = 3 and b=5.
Then
a = a+b (ie 8)
b= a-b (ie 8-5 = 3)
a= a-b (ie 8-3 = 5).
Now these are swapped without using 3rd variable.
I have this two variables:
var a = 1,
b = 2;
My question is how to swap them? Only this variables, not any objects.
Here's a one-liner to swap the values of two variables.
Given variables a and b:
b = [a, a = b][0];
Demonstration below:
var a=1,
b=2,
output=document.getElementById('output');
output.innerHTML="<p>Original: "+a+", "+b+"</p>";
// swap values for variables "a" and "b"
b = [a, a = b][0];
output.innerHTML+="<p>Swapped: "+a+", "+b+"</p>";
<div id="output"></div>
ES6 (Firefox and Chrome already support it (Destructuring Assignment
Array Matching)):
let a = 5, b = 6;
[a, b] = [b, a];
console.log(`${a} ${b}`);
You can do this:
var a = 1,
b = 2,
tmp;
tmp = a;
a = b;
b = tmp;
For readability and maintainability, this can't be beat (at least in JavaScript). Anybody maintaining the code (including you six months from now) will know exactly what's going on.
Since these are integers, you can also use any number of clever tricks1 to swap without using a third variable. For instance you can use the bitwise xor operator:
let a = 1, b = 2;
a = a ^ b;
b = a ^ b;
a = a ^ b;
console.log('a is now:', a);
console.log('b is now:', b);
This is called the XOR swap algorithm. Its theory of operation is described in this Wikipedia article.
1"The competent programmer is fully aware of the limited size of his own skull. He therefore approaches his task with full humility, and avoids clever tricks like the plague." — Edsger W. Dijkstra
Don't use the code below. It is not the recommended way to swap the values of two variables (simply use a temporary variable for that). It just shows a JavaScript trick.
This solution uses no temporary variables, no arrays, only one addition, and it's fast.
In fact, it is sometimes faster than a temporary variable on several platforms.
It works for all numbers, never overflows, and handles edge-cases such as Infinity and NaN.
a = b + (b=a, 0)
It works in two steps:
(b=a, 0) sets b to the old value of a and yields 0
a = b + 0 sets a to the old value of b
Since ES6, you can also swap variables more elegantly:
var a = 1,
b = 2;
[a, b] = [b, a];
console.log('a:', a, 'b:', b); // a: 2 b: 1
You can now finally do:
let a = 5;
let b = 10;
[a, b] = [b, a]; // ES6
console.log(a, b);
Here's a one-liner, assuming a and b exist already and have values needing to be swapped:
var c=a, a=b, b=c;
As #Kay mentioned, this actually performs better than the array way (almost 2x as fast).
You could use a temporary swap variable or XOR.
a = a ^ b
b = a ^ b
a = a ^ b
This is just a basic logical concept and works in every language that supports XOR operation.
edit: see the Comments. Forgot to tell that this works for sure only with integer. Assumed the integer variables from question's thread
Use a third variable like this:
var a = 1,
b = 2,
c = a;
a = b; // must be first or a and b end up being both 1
b = c;
DEMO - Using a third variable
As your question was precious "Only this variables, not any objects. ", the answer will be also precious:
var a = 1,
b = 2
a=a+b;
b=a-b;
a=a-b;
it's a trick
And as Rodrigo Assis said, it "can be shorter "
b=a+(a=b)-b;
Demo:
http://jsfiddle.net/abdennour/2jJQ2/
ES6 Destructuring:
Using an array: [a, b] = [b, a]; // my favorite
Using an object: {a, b} = {a:b, b:a}; // not bad neither
How could we miss these classic oneliners
var a = 1, b = 2
a = ({a:b, _:(b=a)}).a;
And
var a = 1, b = 2
a = (_=b,b=a,_);
The last one exposes global variable '_' but that should not matter as typical javascript convention is to use it as 'dont care' variable.
I see kind of programming olympiad here. One more tricky one-line solution:
b = (function(){ a=b; return arguments[0]; })(a);
Fiddle: http://jsfiddle.net/cherniv/4q226/
Single line swapping
a = a^b^(b^=(a^b));
var a = 5;
var b = 10;
b = [a, a = b][0];
//or
b = [a, a = b];
b = b[0];
//or
b = [a, b];
a = b[1];
b = b[0];
alert("a=" + a + ',' + "b=" + b);
remove or comment the 2 //or's and run with the one set of code
http://jsfiddle.net/USdv8/57/
We are able to swap var like this :
var val1 = 117,
val2 = 327;
val2 = val1-val2;
console.log(val2);
val1 = val1-val2;
console.log(val1);
val2 = val1+val2;
console.log(val2);
first way,
var a = 5, b = 9;
a = a - b;
b = a + b;
a = b - a;
console.log(a, b);
second way
var a = 19, b = 22;
[a, b] = [b, a];
console.log(a, b);
simple and clear answer.
Because I hear this method runs slower:
b = [a, a = b][0];
If you plan on storing your vars in an object (or array), this function should work:
function swapVars(obj, var1, var2){
let temp = obj[var1];
obj[var1] = obj[var2];
obj[var2] = temp;
}
Usage:
let test = {a: 'test 1', b: 'test 2'};
console.log(test); //output: {a: 'test 1', b: 'test 2'}
swapVars(test, 'a', 'b');
console.log(test); //output: {a: 'test 2', b: 'test 1'}
We can use the IIFE to swap two value without extra parameter
var a = 5, b =8;
b = (function(a){
return a
}(a, a=b));
document.write("a: " + a+ " b: "+ b);
Till ES5, to swap two numbers, you have to create a temp variable and then swap it.
But in ES6, its very easy to swap two numbers using array destructuring. See example.
let x,y;
[x,y]=[2,3];
console.log(x,y); // return 2,3
[x,y]=[y,x];
console.log(x,y); // return 3,2
Know more about JavaScript ES6 destructuring
Although the same answer is given previously, but here is a png to describe it.
Simplest form possible:
let a = 2, b = 4;
[b, a] = [a, b];
a more verbose approach would be
let a = 2, b = 4;
a = [a, b];
b = a[0];
a = a[1];