Find Symmetric difference of multi-dimensional and a single-dimensional arrays - javascript

I need some help finding symmetric difference of a multi dimensional array, and a simple array. The first value in each inner array of the multidimensional array cells is the index that compares to the simple array.
So
array1 = [1,4,6,7]
array2 = [[1,"more",12],[8,"some",12]]
the result should be something like:
compare(array1, array2) = //[4,6,7] // there are three differences when compared this way
compare(array2, array1) = //[8,"some",12] // there is only one difference when compared this way
I need to return an array that has both difference of array1 from array2 AND difference from array2 from array1 in the same format as the lead array.
Ideally these are not overwriting the existing arrays but creates a new with the output results. There won't be other array formats besides these two array formats.
Each compare can use a different function if it helps. You don't have to use the same function for both, but if you can, great.
I tried a few permutations of loop comparisons
Also solutions found here
How to get the difference between two arrays of objects in JavaScript
And of the simple array methods here
How to get the difference between two arrays in JavaScript?
But I just am not being successful. Can someone give me a hand, and also explain their solution? Any modern tools are fine as long as its broadly cross browser compatible. All my other code sticks to ES6, so that would be ideal. If whipping out a one liner solution please explain what is going on so I can learn.
Thanks!
Update # Dave, this made sense to me, but after it failed I started trying different filter methods and other techniques in the posts above, without much success.
let newNurkles = new Array();
for(var i = 0; i < nurkles.length; i++){
if(this.activeNurkles.includes(nurkles[i])){
} else {
newNurkles.push(nurkles[i]);// if not then push to array
}
}
console.warn("Nurkles to Add" + newNurkles);

This shows how to perform a disjunctive union on two arrays, one being single dimensional while the other is a multidimensional array.
The symmetry is determined by each element of the single with the first element of each sub-array in the multi. The multi will only be one level deep.
Uses: Array.prototype.map(), Array.prototype.filter()
Steps:
Map over the first input array
For each element, filter the second input to exclude those found in first input
Limit results to only the first array returned
Notes:
o is the iteration of array1
t is iteration of array2
t[0] represents the match key
t[idx] represents the current value of the sub-array being iterated
Results from array2 will produce a multidimensional array
const array1 = [1, 4, 6, 7];
const array2 = [[1, "more", 12],[8, "some", 12], [7, 3, 9], [2, 7, 5, 4], [4, 3]];
const oneToTwo = array2.map((t, idx) => array1.filter(o => t[idx] !== o))[0]
const twoToOne = array1.map(o => array2.filter(t => o !== t[0]))[0]
console.log(oneToTwo);
console.log(twoToOne)

Related

How to go about making an array of the items between two keywords of another array?

Sounds way more confusing than it actually is, but it is simple given an example:
Let's say I have an array like this - [1, 2, 3, 4, 5]
I want the numbers 2, 3 and 4 in their own array like this - [2, 3, 4]
One detail is that the array is completely random! It is all user inputted so I use keywords to find the section I want, like this - ["cmd", "|arg", "stuff", "blah", "|end"]
For this example I would like an array of the items between the keywords |arg and |end that looks like this - ["stuff", "blah"]
I have already found the position in the array of the two keywords but how would I go about making an array of the items between these keywords?
I have tried splicing and I have tried for, but for is not allowed in the game I am coding for and I just cannot seem to find out how to splice it. There has to be a better way and I am not sure what the Method would be called if there even is a Method that can accomplish this.
I don't have any real code to show, as it would be a complete and utter mess if I show it
Just started learning javascript 3 days ago
If you first check to see if that the array contains both values, then you can slice the array into another result array.
let ar = ["cmd", "|arg", "stuff", "blah", "|end"];
let arRes = [];
if(ar.includes("|arg") && ar.includes("|end")){
let idx1 = ar.indexOf("|arg") + 1;
let idx2 = ar.indexOf("|end");
arRes = ar.slice(idx1, idx2)
}
console.log(arRes)

Is there an efficient method JS for this kind of Array manipulation? [duplicate]

This question already has answers here:
Transposing a 2D-array in JavaScript
(25 answers)
Closed 1 year ago.
I have an Array of Arrays, looking like this:
[
[val-1-1, val-1-2],
[val-2-1, val-2-2],
[val-3-1, val-3-2],
...
[val-n-1, val-n-2]
]
The Array can be really long and what I'd like to achieve is "split" this data structure into two Arrays like so:
[val-1-1, val-2-1, val-3-1, ... val-n-1] and [val-1-2, val-2-2, val-3-2, ... val-n-2].
I'm looking for an efficient method to perform this. I know that this is technically easy by looping and using indexes, but I was wondering if there is an efficient method available for this task, as the initial Array is long and I also have multiple of these initial Arrays of Arrays, so looping might take an unnecessarily long time.
For every column, just check if for that column there's an array in the resultant, if there's already an array then simply push the element, else create a new array and then push.
const transpose = (arr) =>
arr.reduce(
(m, r) => (r.forEach((v, i) => ((m[i] ??= []), m[i].push(v))), m),
[]
),
matrix = [
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
];
console.log(transpose(matrix));

Create set of sets javascript

I have a group of arrays that I need to filter out duplicates. It needs to work in such a fashion that within each array, there are no duplicates, and within the total group, there are no two arrays that hold the same values.
The first part is easy - for each inner array, I can apply Set to the array and filter it out. So, given the matrix arrays I can apply the following to filter:
const sets : string[][] = arrays.map(arr=>[...new Set(arr)].sort());
This will give me an array of sets. How can I make this into a set of sets? As in, if sets=[[a, b],[c],[d, a],[c],[e]] I would like setOfSets to equal [[a, b],[c],[d, a],[e]]?
Applying setOfSets = [...new Set(sets)]; would not work, since arrays that are equal are not considered equal by default if they have different addresses. Is there a way to force set to check by value, or another effective way to create this effect?
Edit
Original matrix:
[[a, b, b],
[c,c],
[b,a],
[d,a],
[c,c],
[e,e]]
after creating and sorting sets:
[[a,b],
[c],
[a,b],
[d,a],
[c],
[e]]
desired result:
[[a,b],
[c],
[d,a],
[e]]
If the data in your set is easy to serialize, I would opt for a solution like this:
const data = [
["a", "b", "b"],
["c","c"],
["b","a"],
["d","a"],
["c","c"],
["e","e"]
];
// Create the "hash" of your set
const serializeSet = s => Array
.from(s)
.sort()
.join("___");
// Create a map (or object) that ensures 1 entry per hash
const outputMap = data
.map(xs => new Set(xs))
.reduce(
(acc, s) => acc.set(serializeSet(s), s),
new Map()
);
// Turn your Map and Sets back in to arrays
const output = Array
.from(outputMap.values())
.map(s => Array.from(s));
console.log(output);
To come up with a good hash function for your set, you need to have a good look at your data. For example:
When your arrays consist of single characters from a-z, like in my example above, we can sort those strings using a default sorter and then join the result using a character from outside the a-z range.
If your arrays consist of random strings or numbers, JSON.stringify(Array.from(s).sort()) is safer to use
When your arrays consist of plain objects, you could JSON.stringify its sorted elements, but watch out for differences in the order of objects properties! (e.g. {a: 1, b: 2} vs {b: 2, a: 1})

How get the probability of shuffling an array without getting duplicate Values in javascript

In javascript, I am little bit confused that how to get the actual and accurate probability of shuffling an object in an array.
For example
var numberOfOrder=[
{
id:1
},
{
id:2
},
{
id:3
}
]
From above example The above object can be manipulated in 6 ways By finding the factorial numberOfOrder.length;
But what is the actual way to shuffle that object in an array.
My Try
function newShuffle(value) {
for(var i = value.length-1;i >=0; i--){
var randomIndex = Math.floor(Math.random()*(i+1));
var itemAtIndex = value[randomIndex];
value[randomIndex] = value[i];
value[i] = itemAtIndex
}
return value
}
But the above function won't return accurate value if I run that function 6 times it returning Duplicate Values
What is the correct function to do it
You have to understand the difference between probability and permutations. The second term comes from combinatorics. There are some algorithms that allow to get all possible permutations of array items. Here is one of them:
function permutations(items) {
// single item array - no permutations available
if (items.length == 1) return [items];
var combos = [];
for (var i = 0; i < items.length; i++) {
// first - the current item, rest - array without the current item
var first = items[i], rest = items.slice(0);
rest.splice(i, 1);
// getting permutations of shorter array and for each of them...
permutations(rest).forEach(function(combo){
// prepend the current item
combo.unshift(first);
// save the permutation
combos.push(combo);
});
}
return combos;
}
alert(permutations([ 1, 2, 3 ]).join("\n"));
Update
The recursive algorithm is implemented above. The function permutations gets an array and for each item recursively gets all permutations beginning with current item. At each step of recursion the array is shorter by one item (minus the current item) and at the last step single element array is not being processed because permutations are not available anymore.
Also some comments added to the code.
The last line is just the test to get all permutations of array [1, 2, 3] and to show them via alert. To get more illustrative view all found permutations are glued with new line symbol (.join("\n")).
As stated by the comments and the above answer you need permutations operation. However there are many ways to obtain the permutations of an array. For further information on permutations i would advise you to have a look at Permutations in JavaScript topic.
On the other hand a recursive approach is always much slower compared to a dynamical programming approach. Recently i have come up with a permutations algorithm which seems to be the fastest of all. Check it up

What is the fastest way to make objectIds unique in an Array?

What is the fastest way to make objectIds unique in an Array?
For testing if 2 objectIds are equal, may I convert objectIds to other type, such as numbers or strings?
The easiest way would be to add the ids as keys of an object like this:
var array = [1, 2, 3, 4, 5, 6, 2, 3, 4]
var obj = {}
array.forEach(function(id){obj[id] = true})
array = Object.keys(obj)
Other alternatives would be sorting the array and using binary search and using some data structure like AVL tree.

Categories