I want to pare many arrays and bine any that are identical:
A = [1,2,3];
B = [1,2,3];
C = [1,2,3];
D = [10,11,12];
E = [10,11,12];
F = [10,11,12];
G = [13,14];
H = [13,14];
If there are identical arrays then I'd like to create new arrays out of the identical ones:
I = [1,2,3];
J = [10,11,12];
K = [13,14];
Would I need to iterate through each element in one array against ALL of the elements in the other arrays?
for (var i in A) {
for (var j in B) {
if (A[i] == J[j]) {
// create new arrays
}
}
}
etc...
Then, create new arrays out of the matches? Sounds like a lot of overhead.
What's the best way to acplish this?
Thanks!
I want to pare many arrays and bine any that are identical:
A = [1,2,3];
B = [1,2,3];
C = [1,2,3];
D = [10,11,12];
E = [10,11,12];
F = [10,11,12];
G = [13,14];
H = [13,14];
If there are identical arrays then I'd like to create new arrays out of the identical ones:
I = [1,2,3];
J = [10,11,12];
K = [13,14];
Would I need to iterate through each element in one array against ALL of the elements in the other arrays?
for (var i in A) {
for (var j in B) {
if (A[i] == J[j]) {
// create new arrays
}
}
}
etc...
Then, create new arrays out of the matches? Sounds like a lot of overhead.
What's the best way to acplish this?
Thanks!
Share Improve this question asked Oct 7, 2011 at 23:34 JsusSalvJsusSalv 5171 gold badge8 silver badges22 bronze badges 3- for-in iterates over object keys. It is not a for-each loop and you should not use it on arrays. – hugomg Commented Oct 8, 2011 at 3:11
- @missingno ments are great but try to explain WHY something should not be used or provide a link please. Thanks. – JsusSalv Commented Oct 11, 2011 at 4:07
- I should have been more explicit. Arrays have other properties in addition to the index ones (the ones you really care about) and for-in can iterate over them as well (unless your browser goes all the way to protect you from that). This is specially dangerous if you decide to one day use a library that alters Array.prototype, like MooTools or Prototype, and suddenly lots of spurious stuff starts appearing on your loops. To iterate oven an array you should either use a plain for-loop or one of the iterations methods like .forEach (if that is supported by your browser/libraries) – hugomg Commented Oct 11, 2011 at 12:43
6 Answers
Reset to default 6If you're just trying to finish up with the unique arrays, I would use a hash approach:
var myArrays = [A,B,C,D,E,F,G],
uniques = [],
hashes = {};
for (var i=0; i < myArrays.length; i++) {
var hash = JSON.stringify(myArrays[i]); // or .toString(), or whatever
if (!(hash in hashes)) {
hashes[hash] = true;
uniques.push(myArrays[i]);
}
}
// uniques now holds all unique arrays
Depending on your definition of identical, you could just convert to string and pare those.
if (A.toString() == B.toString()) { //bine }
If you are just paring arrays of primitives- numbers or strings, say- you can pare their string representation.
function simpleArrayMatch(A,B){
return String{A)===String(B);
}
Well... I would do it this way
function bine(arr1, arr2)
{
if(arr1.join(',') === arr2.join(','))
return arr1;
}
or for many arrays
function bine(arrList)
{
var pass = true;
var pareArray = arrList[0];
for(var i in arrList)
pass = pass && (arrList[i].join(',') === pareArray.join(','));
if(pass)
return pareArray;
}
arr = bine([[1,2,3],[1,2,3],[1,2,3]]); // results in [1,2,3]
Suppose all you have inside each array are numbers or texts only, so this maybe a feasible approach without looping through any array:
(See fiddle here)
The code :
A = [1,2,3];
B = [1,2,3];
C = [1,2,3];
D = [10,11,12];
E = [10,11,12];
F = [10,11,12];
G = [13,14];
H = [13,14];
function pareArr(arrList){
var S = '@' + arrList.join('@');
var re = /(@[^@]+)(@.*)?(\1)(@|$)/gi
var afterReplace=''; var i=0;
while(afterReplace!=S && i<100){
afterReplace=S;
S = S.replace( re, "$1$2$4" )
i++
}
return S.substr(1,S.length-1).replace(/@/g,'<br>')
}
$('html').append( pareArr([A,B,C,D,E,F,G,H]) )
Strategy is to join all the array into a string with "@" as the separator. Then use regex to replace all the duplicated piece inside the string, finally split the string then you have the list unique arrays.
The reason to use a while loop in my code is just because I can't write a better regex pattern to remove duplicated piece at once. Looking for a better regex?
I believe so, but at the very least you can use a pare array function to make it easier, even if it's just as slow:
function pareArrays(arr1,arr2)
{
if (arr1.length != arr2.length) return false;
for (var i = 0; i < arr2.length; i++)
{
if (arr1[i].pareArrays)
{ //likely nested arr2ay
if (!arr1[i].pareArrays(arr2[i])) return false;
else continue;
}
if (arr1[i] != arr2[i]) return false;
}
return true;
}
Then, you just need to use this function as you loop through the arrays.