How to map array based on index position - javascript

i have one local date Array Called mainDateArray, i used to call APi Calls to some response, From the resonse i get two Arrays Called "Dates" and "RecordCount". This Dates and record Count have same length and recordCount Array Contains values respective to the "Dates" from the server.
later i need to Draw graph based on this two "mainDateArray" and "recordCount"
if dates Array values does not match with mainDateArray i need to append or push 0 to the "recordsCount" Array
To be more clear
mainDateArray = ["05-May-19","06-May-19","07-May-19","08-May-19","09-May-19","10-May-19","11-May-19"];
dates = ["06-May-19","08-May-19","10-May-19"]; // response date
recordsCount = [20,30,10]; // data for the above dates Array from response
My expected output
op = [0,20,0,30,0,10,0];
example:=> ["05-May-19"=0,"06-May-19"=20,"07-May-19"=0,"08-May-19"=30,"09-May-19"=0,"10-May-19"=10,"11-May-19"=10]
i.e when my response date not includes the maindateArray i need to append 0 in recordCount data any hepls would be helpful for me

Using Array​​.map() and Array​​.indexOf()
var mainDateArray = ["05-May-19", "06-May-19", "07-May-19", "08-May-19", "09-May-19", "10-May-19", "11-May-19"]
var dates = ["06-May-19", "08-May-19", "10-May-19"]
var recordsCount = [20, 30, 10]
var result = mainDateArray.map((v, i) => recordsCount[dates.indexOf(v)] || 0)
console.log(result)

You could create a Map of the date -> recordsCount and then Array#map over mainDateArray array, checking if the date exists in the map or not.
const mainDateArray = [
"05-May-19",
"06-May-19",
"07-May-19",
"08-May-19",
"09-May-19",
"10-May-19",
"11-May-19"
];
const dates = ["06-May-19", "08-May-19", "10-May-19"]; // response date
const recordsCount = [20, 30, 10]; // data for the above dates Array from response
const datesMap = new Map(dates.map((date, idx) => [date, recordsCount[idx]]));
const op = mainDateArray.map(date =>
datesMap.has(date) ? datesMap.get(date) : 0
);
console.log(op);

The easiest way IMO is to use an object to keep track of the counts.
// create object for key (i.e. date) based lookup
var counts = {};
for(var i in mainDateArray){
var date = mainDateArray[i];
counts[date] = 0;
}
// update counts
for(var i in dates){
var date = dates[i];
counts[date] += recordsCount[i];
}
// output
var op = [];
for(var i in mainDateArray){
var date = mainDateArray[i];
op.push(counts[date]);
}

Please try this will work ..
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js">
</script>
<script>
var mainDateArray = ["05-May-19","06-May-19","07-May-19","08-May-19","09-May-
19","10-May-19","11-May-19"];
var output = [];
var dates = ["06-May-19","08-May-19","10-May-19"]; // response date
for(var i=0; i<mainDateArray.length; i++)
{
if($.inArray(mainDateArray[i],dates)!=-1)
{
output.push(mainDateArray[i]);
}
else
{
output.push("0");
}
}
alert(output.toString());
</script>
output = [0,06-May-19,0,08-May-19,0,10-May-19,0]

You can try this
mainDateArray = [
"05-May-19",
"06-May-19",
"07-May-19",
"08-May-19",
"09-May-19",
"10-May-19",
"11-May-19"
];
dates = ["06-May-19", "08-May-19", "10-May-19"]; // response date
recordsCount = [20, 30, 10];
op = [];
for (let i = 0; i < dates.length; i++) {
for (let j = 0; j < mainDateArray.length; j++) {
if (dates[i] === mainDateArray[j]) {
op[j] = recordsCount[i];
} else {
if (!op[j]) op[j] = 0;
}
}
}

Related

How to compare an item in an array to all items in other array and add it into shpreadsheet?

I'm developing a tool and currently I'm stuck with a problem.
I'm writing a code in GoogleAppScript (JavaScript) and I have two columns where I collect data. As a result I've two arrays. Let's call them mainArray and checkArray
I need a code doing this logic:
getting the 1st value of the mainArray, i.e. mainArray[0]
chenking the value if it's equal to checkArray[0], then checkArray[1]... checkArray[i]
if there's a match, then toss it to the garbage bin, and swith to the mainArray[1]
Checking mainArray[1] with all of the values from checkArray, as we did it in p.2
If there's no match with any vals from the checkArray add these value into the 3rd array (finArray)
I've done exaclty the opposite.
for (var j=0; j<checkArr.length; j++) {
for(var i=0; i<mainArr.length; i++) {
if(mainArr[i][0]!==''){
if(checkArr[j][0]==mainArr[i][0])
{
Logger.log('not in the list'+mainArr[i][0])
finArr.push(mainArr[i][0])
break;
}}
But I don't know how to get the code working as I described above.
`
// The Arrays actually are one dimensional
// I prefer to create a one dimensional array
// GetDataArray function creates one dimensional array
function GetDataArray(sht,rng) {
var Data = [] var i = 0;
Logger.log(' Sht Name %s\n rng %s,', sht.getName(), rng)
sht.getRange(rng).getValues() .forEach(
function (row) {
row.forEach( function (cell) {
//Logger.log(cell);
Data[i++] = cell }); } );
return Data
} //
......
var sht = SpreadsheetApp.getActiveSheet()
var rngMain = ....// Provide the range
var rngCheck = ...
var checkArr = GetDataArray(sht, rngCheck)
var mainArr = GetDataArray(sht, rngMain)
var finArr = []
mainArr.forEach( function(cell) {
if (cell == '') continue
if (checkArr.indexOf(cell) != -1) finArr.push(cell)})
function thefunc() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet1');
let vs1 = sh.getRange(1,1,sh.getLastRow(),1).getValues().flat();
let vs2 = sh.getRange(1,2,sh.getLastRow(),1).getValues().flat();
let d = 0;
vs1.forEach((r,i) => {
if(~vs2.indexOf(r[0])) {
sh.deleteRow(i+1-d++);//delete row
}
});
}

How to put a list of data from a for loop into a single array? i'm getting [item] [item] [item] this kind of variable...not [item, item, item]

function chartFunkcio(event) {
let localData;
if (localStorage.getItem('localData') === null) {
localData = [];
} else {
localData = JSON.parse(localStorage.getItem('localData'));
}
//get objects from array between mentioned dates
var result = localData.filter(function (obj) {
return obj.date >= fromdate.value && obj.date <= todate.value;
});
var filtered = result;
//Filtered object from array are sorted after dates
var sortedd = filtered.sort(function (a, b) {
var c = new Date(a.date);
var d = new Date(b.date);
return c - d;
});
for (i = 0; i < sortedd.length; i++) {
var datesforchart = [];
const pushedarray = datesforchart.push(sortedd[i].date);
console.log(pushedarray);
}
}
The local storage data is a tables data. I filtered that data after dates and then i sorted those dates. the sorted date are the one i would like to get in a single array like below mentioned.
i'm getting [item] [item] [item] this kind of data in console log...not an array like this[item, item, item]
i would need that array for implementing a chart, and for that i would neet that the array to look like this ["item", "item2", "item3"]
There's something wrong inside the for loop.
for (i = 0; i < sortedd.length; i++) {
var datesforchart = [];
const pushedarray = datesforchart.push(sortedd[i].date);
console.log(pushedarray);
}
If you try to get new array with just date elements, you can replace the for loop with below code which uses map function.
var datesforchart = sortedd.map(function (item) {
return item.date
});
console.log(datesforchart)
// for (i = 0; i < sortedd.length; i++) {
// var datesforchart = [];
// const pushedarray = datesforchart.push(sortedd[i].date);
// console.log(pushedarray);
// }

Create ranges of dates from a single array of dates

How can I make ranges of dates (from the newest to the oldest) from one array of dates?
I have this array of dates:
["2017-11-16T12:12:50.323Z", "2017-11-15T16:13:24.219Z", "2017-11-14T16:13:55.449Z", "2017-11-13T06:56:21.332Z"]
And I want to have the following ranges of dates result:
["2017-11-16T12:12:50.323Z", "2017-11-15T16:13:24.219Z"]
["2017-11-15T16:13:24.219Z", "2017-11-14T16:13:55.449Z"]
["2017-11-14T16:13:55.449Z", "2017-11-13T06:56:21.332Z"]
I want to achieve this in JavaScript
Assuming that the dates are ordered, you can iterate with for loop up to the last item, and Array#slice each pair:
var dates = ["2017-11-16T12:12:50.323Z", "2017-11-15T16:13:24.219Z", "2017-11-14T16:13:55.449Z", "2017-11-13T06:56:21.332Z"];
var ranges = [];
for(var i = 0; i < dates.length - 1; i++) {
ranges.push(dates.slice(i, i + 2));
}
console.log(ranges);
You could take the actual element of the array and the next for a new item of the result with a Array#reduce pattern which returns the next item for the next loop as actual item.
var data = ["2017-11-16T12:12:50.323Z", "2017-11-15T16:13:24.219Z", "2017-11-14T16:13:55.449Z", "2017-11-13T06:56:21.332Z"],
result = [];
data.sort((a, b) => b > a || -(b < a)); // desc
data.reduce((a, b) => (result.push([a, b]), b));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
var data = ["2017-11-16T12:12:50.323Z", "2017-11-15T16:13:24.219Z", "2017-11-14T16:13:55.449Z", "2017-11-13T06:56:21.332Z"];
var paired = data.sort().slice(0, -1).map(function(d, i) {
return [d, data[i+1]];
})
console.log(paired);
Or using es6 you could do it in one line:
let data = ["2017-11-16T12:12:50.323Z", "2017-11-15T16:13:24.219Z", "2017-11-14T16:13:55.449Z", "2017-11-13T06:56:21.332Z"];
let paired = data.sort().slice(0, -1).map((d, i) => [d, data[i+1]])
console.log(paired)
Since you don't need any advanced sorting, you can just use the default .sort() function which javascript provides.
var datesSorted = dates.sort();
Splitting into pairs can be done in a cycle, because JavaScript doesn't provide any direct "split array into pairs" function.
The final script should look something like this:
var dates = ["2017-11-16T12:12:50.323Z", "2017-11-15T16:13:24.219Z", "2017-11-14T16:13:55.449Z", "2017-11-13T06:56:21.332Z"];
var datesSorted = dates.sort();
var datePairs = function(datesSorted) {
var pairs = [];
for (var i=0 ; i<datesSorted.length ; i+=2) { //iterate by two
if (datesSorted[i+1] !== undefined) { //check if a date has a "pair"
pairs.push ([datesSorted[i], datesSorted[i+1]]); //if it does, push them both
} else {
pairs.push ([datesSorted[i]]);
}
}
return pairs;
};
You're array of date arrays should now be stored in datePairs.

Javascript: Adding final element to array after for loop completes

Explanation of Desired Results
My source is over 30,000 lines of very structured text with incrementing front numbers followed by incrementing back numbers and separated by a colon. Stripping out the non-essentials, I am left with the following sourceArray, truncated for convenience :)
sourceArray = ["001:001", "001:002", "001:003",
"002:001", "002:002",
"003:001", "003:002"];
I am trying to count how many back numbers for each front number and push that to an array. In pseudocode, my final results should look like this:
myArray[totalNumberOf_001_Items, totalNumberOf_002_Items, totalNumberOf_003_Items]
Which in my simple example should give me a final value of:
[3, 2, 2]
Problem and Question
My for loop ends at the end of my data and I am therefore one element short in my array.
How do I make an "extra pass" through the loop or is there another way to get the final element pushed to my array?
var sourceArray = ["001:001", "001:002", "001:003",
"002:001", "002:002",
"003:001", "003:002"
];
var myArray = [];
var frontCounter = 1;
var backCounter = 1;
for (var i = 0; i < sourceArray.length; i++) {
var text = sourceArray[i];
var front = text.substr(0, 3);
front = Number(front);
var back = text.substr(4, 3);
back = Number(back);
if (front == frontCounter) {
backCounter++;
} else {
myArray.push(backCounter - 1);
backCounter = 2;
frontCounter++;
}
}
console.log(myArray); // result [3, 2]
You could use an object like below to keep track of how many times the the piece of text appear, the text would be the keys and as value the number of times they appear. From that you can build you array
var sourceArray = ["001:001", "001:002", "001:003",
"002:001", "002:002",
"003:001", "003:002"];
var frontEncounters = {};
function updateFrontEncounters(frontEncounters, front){
var keys = Object.keys(frontEncounters);
if(keys.indexOf(front) == -1)
{
frontEncounters[front] = 1;
}
else
{
frontEncounters[front] += 1;
}
}
for(var item in sourceArray){
var text = sourceArray[item];
var front = text.substr(0, 3);
var back = text.substr(4, 3);
updateFrontEncounters(frontEncounters, front);
}
var keys = Object.keys(frontEncounters);
var myArr = [];
for(var key in keys)
{
myArr.push(frontEncounters[keys[key]])
}
console.log(myArr);
Use an object to store the "front" numbers along with their count.
for (var i = 0; i < sourceArray.length; i++) {
var num = sourceArray[i].slice(0,3);
counts[num] = counts[num] ? counts[num]+1 : 1;
}
Once done, you can very easily convert that to an array:
var result = Object.keys(counts).map(function (key) {
return counts[key];
});
With ES-2017, it is even easier:
var result = Object.values(counts)
Working Snippet:
var sourceArray = ["001:001", "001:002", "001:003",
"002:001", "002:002",
"003:001", "003:002"];
var counts = {};
for (var i = 0; i < sourceArray.length; i++) {
var num = sourceArray[i].slice(0,3);
counts[num] = counts[num] ? counts[num]+1 : 1;
}
console.log(counts);
var result = Object.keys(counts).map(function (key) {
return counts[key];
});
console.log(result);
// ES-2017
//console.log(Object.values(counts));
Here's an alternative that you can use so that you don't have to go through the entire source of lines (30,000) . Use a while loop so that you can break as soon as you reach a 0; use Map to store the unique number by making the index/frontnumber the key and make its value an object that serves as a counter to keep track of it's total. If the key exists, update the total; if it doesn't, create a new counter object. Then just return the Map by transforming it into the desired array by map'ing it to an array with only the totals.
var sourceArray = ["001:001", "001:002", "001:003",
"002:001", "002:002",
"003:001", "003:002"
];
function getTotal(sourceArray) {
let count = new Map();
let update = item => count.get(item).total++;
let create = item => count.set(item, {total: 1});
const getItem = index => {
let text = sourceArray[index];
return text.substr(0, 3);
}
let index = -1;
let start = 0;
while (index != 0 && start < sourceArray.length) {
index = getItem(start++);
count.has(index) ? update(index) : create(index);
}
return [...count.values()].map(item => item.total);
}
console.log(getTotal(sourceArray));

array object manipulation to create new object

var actual = [
{"country":"UK","month":"JAN","SR":"John P","AC":"24","PR":"2","TR":1240},
{"country":"AUSTRIA","month":"JAN","SR":"Brad P","AC":"64","PR":"12","TR":1700},
{"country":"ITALY","month":"JAN","SR":"Gim P","AC":"21","PR":"5","TR":900},
{"country":"UK","month":"FEB","SR":"John P","AC":"14","PR":"4","TR":540},
{"country":"AUSTRIA","month":"FEB","SR":"Brad P","AC":"24","PR":"12","TR":1700},
{"country":"ITALY","month":"FEB","SR":"Gim P","AC":"22","PR":"3","TR":600},
{"country":"UK","month":"MAR","SR":"John P","AC":"56","PR":"2","TR":1440},
{"country":"AUSTRIA","month":"MAR","SR":"Brad P","AC":"24","PR":"12","TR":700},
{"country":"ITALY","month":"MAR","SR":"Gim P","AC":"51","PR":"5","TR":200}
];
var expect = [
{month:"JAN",val: {"UK":"24","AUSTRIA":"64","ITALY":"21"}},
{month:"FEB",val: {"UK":"14","AUSTRIA":"24","ITALY":"22"}},
{month:"MAR",val: {"UK":"56","AUSTRIA":"24","ITALY":"51"}}
];
I have array of objects which i need to reshape for one other work. need some manipulation which will convert by one function. I have created plunker https://jsbin.com/himawakaju/edit?html,js,console,output
Main factors are Month, Country and its "AC" value.
Loop through, make an object and than loop through to make your array
var actual = [
{"country":"UK","month":"JAN","SR":"John P","AC":"24","PR":"2","TR":1240},
{"country":"AUSTRIA","month":"JAN","SR":"Brad P","AC":"64","PR":"12","TR":1700},
{"country":"ITALY","month":"JAN","SR":"Gim P","AC":"21","PR":"5","TR":900},
{"country":"UK","month":"FEB","SR":"John P","AC":"14","PR":"4","TR":540},
{"country":"AUSTRIA","month":"FEB","SR":"Brad P","AC":"24","PR":"12","TR":1700},
{"country":"ITALY","month":"FEB","SR":"Gim P","AC":"22","PR":"3","TR":600},
{"country":"UK","month":"MAR","SR":"John P","AC":"56","PR":"2","TR":1440},
{"country":"AUSTRIA","month":"MAR","SR":"Brad P","AC":"24","PR":"12","TR":700},
{"country":"ITALY","month":"MAR","SR":"Gim P","AC":"51","PR":"5","TR":200}
];
var outTemp = {};
actual.forEach(function(obj){ //loop through array
//see if we saw the month already, if not create it
if(!outTemp[obj.month]) outTemp[obj.month] = { month : obj.month, val: {} };
outTemp[obj.month].val[obj.country] = obj.AC; //add the country with value
});
var expected = []; //convert the object to the array format that was expected
for (var p in outTemp) {
expected.push(outTemp[p]);
}
console.log(expected);
Iterate through array and create new list
var actual = [
{"country":"UK","month":"JAN","SR":"John P","AC":"24","PR":"2","TR":1240},
{"country":"AUSTRIA","month":"JAN","SR":"Brad P","AC":"64","PR":"12","TR":1700},
{"country":"ITALY","month":"JAN","SR":"Gim P","AC":"21","PR":"5","TR":900},
{"country":"UK","month":"FEB","SR":"John P","AC":"14","PR":"4","TR":540},
{"country":"AUSTRIA","month":"FEB","SR":"Brad P","AC":"24","PR":"12","TR":1700},
{"country":"ITALY","month":"FEB","SR":"Gim P","AC":"22","PR":"3","TR":600},
{"country":"UK","month":"MAR","SR":"John P","AC":"56","PR":"2","TR":1440},
{"country":"AUSTRIA","month":"MAR","SR":"Brad P","AC":"24","PR":"12","TR":700},
{"country":"ITALY","month":"MAR","SR":"Gim P","AC":"51","PR":"5","TR":200}
];
var newList =[], val;
for(var i=0; i < actual.length; i+=3){
val = {};
val[actual[i].country] = actual[i]["AC"];
val[actual[i+1].country] = actual[i+1]["AC"];
val[actual[i+2].country] = actual[i+2]["AC"];
newList.push({month: actual[i].month, val:val})
}
document.body.innerHTML = JSON.stringify(newList);
This is the correct code... as above solution will help you if there are 3 rows and these will be in same sequnece.
Here is perfect solution :
var actual = [
{"country":"UK","month":"JAN","SR":"John P","AC":"24","PR":"2","TR":1240},
{"country":"AUSTRIA","month":"JAN","SR":"Brad P","AC":"64","PR":"12","TR":1700},
{"country":"ITALY","month":"JAN","SR":"Gim P","AC":"21","PR":"5","TR":900},
{"country":"UK","month":"FEB","SR":"John P","AC":"14","PR":"4","TR":540},
{"country":"AUSTRIA","month":"FEB","SR":"Brad P","AC":"24","PR":"12","TR":1700},
{"country":"ITALY","month":"FEB","SR":"Gim P","AC":"22","PR":"3","TR":600},
{"country":"UK","month":"MAR","SR":"John P","AC":"56","PR":"2","TR":1440},
{"country":"AUSTRIA","month":"MAR","SR":"Brad P","AC":"24","PR":"12","TR":700},
{"country":"ITALY","month":"MAR","SR":"Gim P","AC":"51","PR":"5","TR":200}
];
var tmpArray = [];
var obj =[];
for(var k=0; k<actual.length; k++){
var position = tmpArray.indexOf(actual[k].month);
if(position == -1){
tmpArray.push(actual[k].month);
val = {};
for(var i=0; i<actual.length; i++){
if(actual[i].month == actual[k].month){
val[actual[i].country] = actual[i]["AC"];
}
}
obj.push({month: actual[k].month, val:val});
}
}

Categories

Resources