How to get unique values from two 2D arrays in JavaScript - javascript

I am trying to get unique values from two arrays which looks like that:
array[{A,B,C},{C,D,E},{1,3,2},....]
both looks the same.
I tried to add them using concat and the get unique values from looping.
So I ended up with this:
function uniqueValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var srcSheet = ss.getSheetByName("arr1");
const array1 = srcSheet.getRange(1, 1, srcSheet.getLastRow(), srcSheet.getLastColumn()).getValues();
var srcSheet1 = ss.getSheetByName("arr2");
const array2 = srcSheet1.getRange(1, 1, srcSheet1.getLastRow(), srcSheet1.getLastColumn()).getValues();
var dodaj = array1.concat(array2);
for (var i=0; i<dodaj.length; i++) {
var listI = dodaj[i];
loopJ: for (var j=0; j<dodaj.length; j++) {
var listJ = dodaj[j];
if (listI === listJ) continue;
for (var k=listJ.length; k>=0; k--) {
if (listJ[k] !== listI[k]) continue loopJ;
}
dodaj.splice(j, 1);
}
}
var result = ss.getSheetByName("test").getRange(2, 5, dodaj.length, 3).setValues(dodaj);
//Logger.log(dodaj);
}
It was working well when array looked like this array[{A,B},{C,D}] but with three elements it started to return duplicates as well... I have no idea what can be wrong.

If I understand you correctly, you want to retrieve the unique rows from the values in arr1 and arr2. That is to say, you want to remove duplicate inner arrays from dodaj.
After using concat to merge the two arrays, you could do the following:
Use JSON.stringify() to transform each inner array to a string, in order to compare them without iterating through them.
Use the Set constructor and the spread syntax in order to remove the duplicate strings (see this answer).
Transform the strings back to arrays with JSON.parse().
Code snippet:
var dodaj = array1.concat(array2);
dodaj = [...new Set(dodaj.map(JSON.stringify))].map(JSON.parse);
var result = ss.getSheetByName("test").getRange(2, 5, dodaj.length, dodaj[0].length).setValues(dodaj);

Related

Adding a single array of an array into an array of a multidimensional array in Excel Scripts/ Javascript

looking to add a single array into a multidimensional array or an array of arrays.
for example:
Data = [["A","B","C","D"]];
NewData =[[1,2,3,4],[5,6,7,8],[9,10,11,12]];
CombinedData = [];
for(i=0; i< NewData.length; i++){
CombinedData.push(...Data,NewData[i]);
}
However the above results in this:
"CombinedData =[["A","B","C","D"],[1,2,3,4],["A","B","C","D"],[5,6,7,8],["A","B","C","D"],[9,10,11,12],["A","B","C","D"]....]"
Where what I am looking for is this:
"CombinedData =[["A","B","C","D",1,2,3,4],["A","B","C","D",5,6,7,8],["A","B","C","D",9,10,11,12],]"
This is in ExcelScripts or office scripts which I know is pretty new but just looking for some sort of direction.
You need to spread both arrays and wrap in in brackets to make a new array.
const Data = ["A","B","C","D"];
const NewData =[[1,2,3,4],[5,6,7,8],[9,10,11,12]];
var CombinedData = [];
for(i=0; i< NewData.length; i++){
CombinedData.push([...Data,...NewData[i]]);
}
console.log(CombinedData);
Also, you could just use map instead of the for loop:
const Data = ["A","B","C","D"];
const NewData =[[1,2,3,4],[5,6,7,8],[9,10,11,12]];
var CombinedData = NewData.map(x=>[...Data, ...x]);
console.log(CombinedData);

Combining elements of 2 dimentional array

I have an JavaScript array:
var arr = [["A",["05",90]],["A",["04",240]],["A",["03",235]],["B",["00",123]],["B",["01",234]]];
I want final array to look like:
var final = [["A",[["05",90],["04",240],["03",235]]],["B",[["00",123],["01",234]]]];
The final array is formed by combining all the 2nd element of 2 dimensional array when the 1st element matches.
Please advice how can this be achieved in JavaScript
Object keys are generally the easiest way to create groups like this
var tmp = {}; // temporary grouping object
// loop over data
arr.forEach(function (item) {
// check if group started
if (!tmp.hasOwnProperty(item[0])) {
tmp[item[0]] = [];
}
// push data to group
tmp[item[0]].push(item[1]);
});
// map temp object to results array
var results = Object.keys(tmp).map(function (key) {
return [key, tmp[key]];
});
DEMO
If you start with the array you gave:
var arr = [["A",["05",90]],["A",["04",240]],["A",["03",235]],["B",["00",123]],["B",["01",234]]];
then create a new array to store the values:
var final = [];
and simply combine all of the third-level elements (such as ["05",90] and ["01",234]) of each second-level ones (such as "A" and "B") by looping through the array:
for(var i = 0; i < arr.length; i++) {
var found = false;
for(var j = 0; j < final.length; j++) {
if(arr[i][0] == final[j][0]) {
final[j][1].push(arr[i][1]);
found = true;
break;
}
}
if(!found) {
final[final.length] = [arr[i][0], [[arr[i][1][0], arr[i][1][1]]]];
}
}
This is essentially a sorting method: if the "key" is equal to one in the final array, then it adds it to that one. If not, then appends it to the end of final.
Here's the working example on JSFiddle: link.
This outputs the array:
["A", [["05", 90], ["04", 240], ["03", 235]]], ["B", [["00", 123], ["01", 234]]]
as requested.
Also, as #PaulS commented, it would be recommended to use Objects instead as Strings, to make them Key-Value pairs. But in my answer I stuck with arrays.

Array sort() sorted the actual array list after assigning to another array as well

Result holds dynamic value in array but after sorting the result also get sorted but I don't want it to get sorted. But after sorting its also get sorted. Why is that?
$scope.arreyList = result;
var sorted_arr = $scope.arreyList.sort();
$scope.countRowSame = [];
for (var i = 0; i < sorted_arr.length - 1; i++) {
if (sorted_arr[i + 1].SupplierId == sorted_arr[i].SupplierId) {
$scope.countRowSame.push(sorted_arr[i].SupplierId);
}
}
sort sorts the array in place. So this line:
var sorted_arr = $scope.arreyList.sort();
sorts the $scope.arreyList, and returns a reference to that same array. It doesn't create a sorted copy of the array.
If you want to make a copy and sort that, use slice:
var sorted_arr = $scope.arreyList.slice(0).sort();
In addition to #Crowder's answer you can use angular.copy() to clone the array.
$scope.arreyList = angular.copy(result);
var sorted_arr = $scope.arreyList.sort();

Get Unique Values from Array

var arr = ["THYROID","CARDIAC","CARDIAC,DIABETES","METABOLIC,ARTHRITIS","RENAL DISEASES,DIABETES","LIVER DISEASES,HEPATITIS","LIVER DISEASES,CANCER,METABOLIC","LIVER DISEASES,HEPATITIS,ARTHRITIS,METABOLIC"]
Above is my Code,
I need to fetch unique Values from this array using Javascript.
Like, what i expect is:
If i ask for Unique Values , it should get me :
var arr = ["THYROID","CARDIAC","DIABETES","METABOLIC","RENAL DISEASES","LIVER DISEASES,"CANCER",ARTHRITIS","HEPATITIS"]
If you have an array of strings, you can just create an object using those strings as keys, then get the keys from that object.
Create the object
for (var t = {}, i = 0; i < arr.length; i++)
t[arr[i]] = 0;
Create an array from the objects keys
// Modern browsers only
arr = Object.keys(t);
// In older browsers you can use the polyfill from the link below,
// or just loop through the object like this:
arr = [];
for (var k in t)
arr.push(k);
Object.keys

What kind of array is this in JavaScript?

I have an array that looks like this:
var locationsArray = [['title1','description1','12'],['title2','description2','7'],['title3','description3','57']];
I can't figure out what type of array this is. More importantly, I'm gonna have to create one based on the info there. So, if the number on the end is greater than 10 then create a brand new array in the same exact style, but only with the title and description.
var newArray = [];
// just a guess
if(locationsArray[0,2]>10){
//add to my newArray like this : ['title1','description1'],['title3','description3']
?
}
How can I do it?
Try like below,
var newArray = [];
for (var i = 0; i < locationsArray.length; i++) {
if (parseInt(locationsArray[i][2], 10) > 10) {
newArray.push([locationsArray[i][0], locationsArray[i][1]]);
}
}
DEMO: http://jsfiddle.net/cT6NV/
It's an array of arrays, also known as a 2-dimensional array. Each index contains its own array that has its own set of indexes.
For instance, if I retrieve locationsArray[0] I get ['title1','description1','12']. If I needed to get the title from the first array, I can access it by locationsArray[0][0] to get 'title1'.
Completing your example:
var newArray = [];
// just a guess
if(locationsArray[0][2]>10){
newArray.push( [ locationsArray[0][0], locationsArray[0][1] ] );
}
throw that in a loop and you're good to go.
It's an array of arrays of strings.
Each time there is this : [], it defines an array, and the content can be anything (such as another array, in your case).
So, if we take the following example :
var myArray = ["string", "string2", ["string3-1", "string3-2"]];
The values would be as such :
myArray[0] == "string"
myArray[1] == "string2"
myArray[2][0] == "string3-1"
myArray[2][1] == "string3-2"
There can be as many levels of depth as your RAM can handle.
locationsArray is an array of arrays. The first [] operator indexes into the main array (e.g. locationsArray[0] = ['title1','description1','12']) while a second [] operation indexes into the array that the first index pointed to (e.g. locationsArray[0][1] = 'description1').
Your newArray looks like it needs to be the same thing.
It's an array of array.
var newArray = [];
var locationsArray = [
['title1','description1','12'],
['title2','description2','7'],
['title3','description3','57']
];
for(i = 0; i < locationsArray.length; i++) {
if (locationsArray[i][2] > 10) {
newArray .push([locationsArray[i][0], locationsArray[i][1]]);
}
}
console.log(newArray );

Categories

Resources