Hi I'm having trouble comparing two strings that should really be the same but when I evaluate it in alert(f==g) it evaluates to false.
var oTrackCarriers = {
"9045": [
["A"],
["B"],
["C"]
],
"9046": [
[" "]
]
};
var oHeadingCarriers = {
"Ripplefold": [
["A"],
["B"],
["C"],
["D"]
],
"PinchPleat": [
["C"],
["D"]
]
};
var HeadingList = oHeadingCarriers["Ripplefold"];
var TrackList = oTrackCarriers["9045"]
var f = (TrackList[0].valueOf());
var g = (HeadingList[0].valueOf());
alert(f);
alert(g);
alert(f == g);
Is this because I'm putting the two values into an array beforehand?
Here's it running http://jsfiddle.net/sQrST/17/embedded/result/
thanks for the help
var oTrackCarriers = { "9045": [["A"], ["B"], ["C"]],
"9046": [[" "]] };
var TrackList = oTrackCarriers["9045"]; // TrackList = [["A"], ["B"], ["C"]]
var f = (TrackList[0].valueOf()) // f = ["A"]
alert() displays arrays in a non intuitive way, so the fact that f (and g) are arrays is hidden, and comparisons of arrays don't do an element wise comparison of the elements, it compares if the variables reference the same array;
["A"] == ["A"]
> false
"A" == "A"
> true
a = ['A']
b = a
a == b
> true
["A"] is an array. You can either get the string value with TrackList[0][0] and HeadingList[0][0] or check if every string contained in TrackList[0] and HeadingList[0] are equals. Usually, two arrays are always differents when comparing them directly. In fact, an array is equal to another if their memory addresses are the same, which makes no sense.
Dont compare the arrays ... change to this:
alert(f[0]);
alert(g[0]);
alert(f[0] == g[0]);
and now its 'true'
Related
I have function that returns a string or an array of strings depending on some rules defined inside.
So we want to basically take that String/Array and basically make sure that we end up with an array of strings with an additional string 'X' added as last item to that array.
concat is a very useful array method for that purpose, since it both accepts an array as argument or a non-array. Either way it will concatenate those/that value(s) to the array on which it is called, and return the result.
In addition, concat accepts more than one argument, so you can at the same time add some other value, like "X":
function f(b) {
if (b) return ["a", "b"];
else return "a";
}
// call f twice, the first time it returns "a", the second time ["a", "b"]
for (let b = 0; b < 2; b++) {
let res = [].concat(f(b), "X");
console.log(res);
}
function append(vec, word){
if (typeof(vec)==="string"){
vec = [vec]
}
return vec.concat(word)
}
a = "foo"
b = ["foo","bar"]
append(a,"xyz") //-> [ 'foo', 'xyz' ]
append(b,"xyz") //-> [ 'foo', 'bar', 'xyz' ]
When you're dealing with a variable that may or may not already be an array, the .flat() method comes in handy, so you can wrap it in an array and then make sure the array is only one level deep.
This is how I would achieve this, and there are two different ways you could write up this function, so I'll include both below:
const stringExample = "test";
const arrayExample = ["1", "2", "3"];
const xStrings1 = strings => [...[strings].flat(), "X"]; // option 1
const xStrings2 = strings => [strings, "X"].flat(Infinity); // option 2
console.log(xStrings1(stringExample)); // -> ["test", "X"]
console.log(xStrings2(stringExample)); // -> ["test", "X"]
console.log(xStrings1(arrayExample)); // -> ["1", "2", "3", "X"]
console.log(xStrings2(arrayExample)); // -> ["1", "2", "3", "X"]
I've benchmark-tested both functions with both examples of sample data, and they are nearly identical in performance for both types. Neither is conclusively faster than the other, so it's up to you which you would prefer to use.
Input:
["A", "B", "C"]
Expected output:
["A", "B", "C", "A, B", "A, C", "B, C", "A, B, C"]
This is a simple example case, but the function should work for strings and arrays of all lengths. Strings may have certain letters repeated, e.g. "AABB", which is distinct from "A" and "B". Order by number of elements first then alphanumerical sort is desired but not required for this solution.
You can use a permutation function, and then join certain strings after spliting them:
const arr = ["A", "B", "C"];
function getCombinations(chars) {
var result = [];
var f = function(prefix, chars) {
for (var i = 0; i < chars.length; i++) {
result.push(prefix + chars[i]);
f(prefix + chars[i], chars.slice(i + 1));
}
}
f('', chars);
return result;
}
const permutations = getCombinations(arr).map(e => e.length > 1 ? e.split("").join(", ") : e);
console.log(permutations);
Permutations function from this answer.
This is actually something I have been working on in scheme lately, what you appear to be looking for is a procedure that generates a power set from a set input. There just happens to be a recursive algorithm that already exists to solve this problem, but it is based on math that I don't need to go into here.
Here is a simple JavaScript implementation from another post here that I modified for your problem:
const myList = ["A", "B", "C"];
const powerSet =
theArray => theArray.reduce(
(subsets, value) => subsets.concat(
subsets.map(set => [value,...set])
),
[[]]
);
console.log(powerSet(myList));
This is what I ended up using as a basis for my implementation:
https://www.w3resource.com/javascript-exercises/javascript-function-exercise-21.php
This question already has answers here:
How to compare arrays in JavaScript?
(55 answers)
Closed 3 years ago.
I am fairly new to javascript and for some reason my program doesn't work. I have a dictionary using the key set to a string and the value euqal to an array full of booleans, I.E:
dict = {x: [true, false]}
but for some reason when I run the dictionary through an if statement, like
if (dict[x] == [true, false]) {do something }
it fails to trigger. I was wondering what I am doing wrong
Comapre using Array.every
You can use Array.every to check if all items in an array verify a certain condition
With that you can check if all items in arrayOne are equal to the item at index i from arrayTwo
Here's an example
const isEqualArrays = (a, b) => a.length === b.length && a.every((x, i) => x === b[i]);
const isEqualDicts = (a, b) => isEqualArrays(a.x, b.x);
const first = { x: [true, false, true] };
const second = { x: [true, false, true] };
const unequal = { x: [true, true, true] };
console.log(isEqualDicts(first, second));
console.log(isEqualDicts(first, unequal));
Use JSON.stringify
Another way that works with your example, is to convert the objects ("dicts") into strings and then compare those strings. It looks like this
const compareDicts = (a, b) => JSON.stringify(a) === JSON.stringify(b);
const first = { x: [true, false, true] };
const second = { x: [true, false, true] };
const unequal = { x: [true, true, true] };
console.log(compareDicts(first, second));
console.log(compareDicts(first, unequal));
Arrays and Objects are not primitive types but reference types in JavaScript.
This means that when comparing arrays and objects, you are actually comparing the references to these entities, and not their content. When you assign this array to another variable, you are simply making that variable reference the same content, but you are not copying this content:
const a = [1, 2, 3];
const b = [1, 2, 3];
console.log(a !== b);
const c = a;
console.log(a === c);
c[0] = 10;
console.log(a);
In your case, if you want to make sure your array contains true followed by false, you can use Array.every() or more simply just use array indexing to check the elements since the array is short:
const a = [true, false];
if (a.every((x, i) => x === [true, false][i])) {
console.log('same content');
}
if (a[0] === true && a[1] === false) {
console.log('same content');
}
You can not compare complex structures like arrays and objects because the equality checking is actually looking at specific memory locations. Every time you create a new object or array, that variable is pointing to a new, unique place in memory. You would have to iterate through the keys/indices that hold primitive values and check each one for equality with your other structure.
Extra credit: the square and curly braces are called Array literals and Object literals. They are essentially syntactic sugar for new Array or new Object.
Additionally, the reason you can check equality on strings, booleans, and numbers is because each value of each type (true, false, 7, 'hello world', 'blue', 42), actually points to a unique place in memory. For example: when you write
var str = 'yellow'
the variable str is now pointing to a place in memory that is associated with the six characters that comprise the word ‘yellow’. This is the actual reason that equality checking is possible.
var str2 = 'yel' + 'low'
Results in the same combination of characters, which results in a reference to the same memory address as what str’s valueOf function points to. Therefore:
str === str2 // true
I hope that helps. There’s much more down this rabbit hole, but this should get you started.
Currently I have an array using an increasing index:
var idx = 1;
var a = [];
a[idx++] = "apple";
a[idx++] = "orange";
...
console.log(a[2]);
And only accessing it by [], not using array specific functions, like length, indexOf, ...
Apparently following is also working in this case:
var a = {};
So, which one should I prefer in such case? For example any performance difference between them?
[ ] denotes an array. Arrays only hold values:
var a1 = [1, 2, 3, 4]
As #Qantas pointed out, array can hold more than just values. An array can even contain another array and/or object:
var a2 = [1, 2, ["apple", "orange"], {one: "grape", two: "banana"}];
{ } denotes an object. Objects have key-value pairs like
var a3 = {one: 1, two: 2}
In your case, it's really a matter of how you would like to be able to access the data. If you are only interested in knowing "apple", "pear", etc. Go ahead and use an array. You can access it via it's index
a1[0]; // outputs 1
a1[1]; // outputs 2
or you can iterate over it with a loop. If you use the curly braces, (given the example I gave) you could access it with
a3.one; // outputs 1
a3["two"]; // outputs 2
It's really up to you on how it would best fit your needs in this case. For a more extensive discussion see this article.
The difference is using square brackets will create an Array object while using curly brackets creates a plain object. For example:
a = [];
a[1] = 'a';
b = {};
b[1] = 'b';
a.length; // returns 2
b.length; // is undefined
a.push('z'); // add 'z' to the end of a
b.push('z'); // generates an error - undefined is not a function
// because plain objects don't have a push method
Read the MDN documentation on Array objects to know more about arrays: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
I have programmed in Microsoft Small Basic in the past, which can have arrays like this:
Array[1][1] = "Hello"
Array[1][2] = "Hi"
Array[1][2] = "Hey"
Now, in Javascript, I know how to create a single array (var Array = New Array()) but are there any array types like the ones above?
There are no true multidimensional arrays in JavaScript. But you can create an array of arrays like you have done.
JavaScript's arrays are just objects with a special length property and a different prototype chain.
Yes, you need to create an array of arrays:
var x = new Array(3);
x[0] = new Array(3);
x[1] = new Array(3);
x[2] = new Array(3);
x[0][0] = "Hello";
etc.
Remember that indexing is zero-based.
Edit
Or:
var x=[];
x[0] = [];
x[1] = [];
x[2] = [];
...
x[0][0] = "Hello";
etc.
You can achieve this:
var o = [[1,2,3],[4,5,6]];
Also you can use the fact that objects in javascript are dictionaries:
var o;
o["0"] = {'0':1, '1':2, '1':3};
var x = o["0"]["1"]; //returns 2
The easiest way would be to just declare an array, and initialize it with a bunch of other arrays. For example:
var mArray = [
[1,2,3],
[4,5,6]
];
window.alert(mArray[1][1]); //Displays 5
As others have pointed out, this is not actually a multi-dimentional array in the standard sense. It's just an array that happens to contain other arrays. You could just as easily have an array that had 3 other arrays, an int, a string, a function, and an object. JavaScript is cool like that.
You can create arrays statically in JS like this:
var arr = [
[1, 2, 3, 4],
[8, 6, 7, 8]
];
Note that since this is not a true "multidimentional array", just an "array of arrays" the "inner arrays" do not have to be the same length, or even the same type. Like so:
var arr = [
[1, 2, 3, 4],
["a", "b"]
];