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.
Related
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);
Hello stackoverflow members.
I come with the following problem:
To start we have
var myArray = [[array1],[array2],[array3],[arrayN],...];
where each array is filled with a known number of strings such as
var array1 = ["a","b"], array2 = ["1","2"], array3=["&","é"];....
and so on.
I'm looking for a method to get this result:
expected result ===> a1&;a1é;a2&;a2é;b1&;b1é;b2&;b2é; ....
If the number of dimension were fixed I could use for loops to iterate and build the result, BUT here the problem is that I want to be able to enter N arrays in the main array myArray and by doing so, I change the depth of the nested loops.
If not do you have some ideas to put me on the track of the solution to this?
Thanks!
EDIT by the way this is what i experimented:
for (i=0; i<myArray[0].length; i++){
for (var j =0; j<myArray[1].length; i++){
for(var k = 0; k<myArray[2].length; k++{
console.log(i+j+k);
}
}
}
BTW i can't find a way to describe a function which would nest N for loops where N is myArray.length + 1 (the number of arrays in myArray).
EDIT: i found an iterative way of doing it and wanted to share the solution:JSFiddle
To get a flat list of all cells, something like the following recursive function should work (if you have a non-empty array of arrays, and all array items are strings):
function makeFlatList(inputArray) {
if (inputArray.length == 1) { // if this array has only one array inside
return inputArray[0]; // return the array inside
} else {
var outArr = [];
var arrayShifted = inputArray.slice(1); // remove first subarray from inputarray
var arrayShiftedFlat = makeFlatList(arrayShifted); // recursive call
for (var i=0; i<inputArray[0].length ; i++) { // loop over first array
for (var j=0; j<arrayShiftedFlat.length; j++) {
outArr.push(inputArray[0][i]+arrayShiftedFlat[j]); // add items to outArr
}
}
return outArr;
}
}
Working JSBin here
I have two arrays. The first is for strings and the second is an array for their number of occurrences.
I am trying to get the top 10 most occurrences of words in the first array. I sorted it but somehow I only sort it alphabetically and the second array respectively corresponds to their number of occurrences.
How can I sort the second array from biggest to lowest and, at the same time, sort the first array that match the order of the second?
I'm having trouble inserting my json to my highcharts and I found out why, the numbers should be in square brackets [] I tried already inserting [] in 1 but still does not work please see my post I edit it
this is the data that i should insert in the highchart
[{"name":"#murrayftw","data":[46]},
{"name":"#job","data":[37]},
{"name":"#jobs","data":[25]},
{"name":"#favnashvine","data":[16]},
{"name":"#rollersmusicawards","data":[14]},
{"name":"#soa","data":[13]},
{"name":"#tweetmyjobs","data":[12]},
{"name":"#sman1boyolangu","data":[12]},
{"name":"#supernatural200thepisode","data":[12]},
{"name":"#veteransday","data":[12]}]
Try using a custom compare function with your .sort() call! Check out the documentation here.
I would, in this example (probably not the best way):
Have the unsorted "count" array
Have the unsorted word array
Sort the word array (with a custom function described below)
Sort the count array (no custom function)
The custom compare function would probably be a simple lookup and return the corresponding value in the unsorted count array. (i.e. if the word "a" is 0th index and its relevant count amount is in the 0th index of the count array, return count[0])
If you cannot work with an object try using nested for loops:
var array1 = ['z', 'd', 'e', 'f', 't'], arr1Count = array1.length;
var array2 = [1, 12, 5, 7, 3];
var sortedArray2 = array2.sort(function(x, y) {return y - x});
var i, j, sortedArray1 = [];
for (i = 0; i < arr1Count; i++) {
for (j = 0; j < arr1Count; j++) {
if (array2[j] === sortedArray2[i]) sortedArray1.push(array1[j]); //iterate through the unsorted numeric array (array2) and when it matches the sortedArray2, push this index of array1 into the sortedArray1
}
}
This will create an array of objects that are then sorted by count.
var hashtags = {},
counts = [];
for (var i in data)
{
if(data[i].lang == "en")
{
for (var j in data[i].entities.hashtags)
{
var text = data[i].entities.hashtags[j].text;
if(text) {
if(hashtags[text]) {
hashtags[text].data[0]++;
} else {
hashtags[text] = {
name: text,
data: [1]
};
counts.push(hashtags[text]);
}
}
}
}
}
counts.sort(function(a, b) { return b.data[0] - a.data[0]; });
Simple - don't use 2 arrays but one collection which every element is an object
I took the basics from this post: Sorting JavaScript Object by property value
and completed the demo:
var collection = {car:300, bike:60, motorbike:200, airplane:1000, helicopter:400, rocket:8*60*60}
var sortable = [];
for (var item in collection)
sortable.push([item, collection[item]])
sortable.sort(function(a, b) {return a[1] - b[1]})
collection = {};
for (var i in sortable)
{
collection[sortable[i][0]] = sortable[i][1];
}
console.log(collection);
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 );
i have a JavaScript array of string arrays: array1; array2 ; array3 which i need to break and then access the individual array. how can i do that?
You can use the split method:
var str = 'array1; array2 ; array3';
var arr = str.split('; ');
To access the individual array parts, you need to use index which starts from 0:
alert(arr[0]); // shows first item
alert(arr[1]); // shows second item
alert(arr[2]); // shows third item
Or you can loop through the array like this too:
for(var i = 0; i < arr.length; i++)
{
alert(arr[i]);
}