getting specific values from an object - arrays

(I am working with Angular but this is not an angular specific problem).I have a json object that i am trying to disect. I've been trying to get my head around this and have come up with a complicated script with nested for loops that isn't working. The object consists of 3 arrays. The first array is an array of fieldnames. The third array is an array of arrays that correspond to the field names like so:
object = {"fields" : [array], "type" : [array], "values" : [array]}
where:
fields = ["user","bananas","pies","apples","pears","mangos","date"]
values = [["Bongo","12","2","1","2","4","05-02-2015"], ["Mongo","12","23","15","22","43","05-02-2015"], ["Congo","15","32","21","23","44","06-02-2015"]]
What i want to do is count the amount of fruit that all users had on a specific date. for instance i want to know how many bananas all users had on "06-02-2015".
I can post my code, but i think that would only work confusing as it's probably wrong and redundant.
update:
I've tried the filter but can't get it to work because the values inside object.values don't have a name. So i think it should be something like this:
var fruits = $filter('filter')(object.value, {???[6] : "2015-04-29 00:00:00"}, true);
I'm not sure what the ??? should be.
solved:
simply removing the name did the trick.
var fruits = $filter('filter')(object.value, "2015-04-29 00:00:00", true);

This script should group the values by date:
var fields = ["user","bananas","pies","apples","pears","mangos","date"];
var values = [["Bongo","12","2","1","2","4","05-02-2015"], ["Mongo","12","23","15","22","43","05-02-2015"], ["Congo","15","32","21","23","44","06-02-2015"]];
var result = {};
for (var j = 0; j < values.length; j++) {
if (!result.hasOwnProperty(values[j][fields.length - 1]))
result[values[j][fields.length - 1]] = {};
for (var i = 1; i < fields.length - 1; i++) {
if (!result[values[j][fields.length - 1]][fields[i]])
result[values[j][fields.length - 1]][fields[i]] = parseInt(values[j][i], 10);
else
result[values[j][fields.length - 1]][fields[i]] += parseInt(values[j][i], 10);
}
}
console.log(result);

What you need is a filter:
var fruits = $filter('filter')(object, {date: $choosenDate}, true);
Then, if you want to split fruit by type, you can use angular.forEach to iterate on the nev fruits var

This would be a lot simpler if the structure of the arrays wasn't bananas, so to speak.
var fields = ["user","bananas","pies","apples","pears","mangos","date"];
var values = [["Bongo","12","2","1","2","4","05-02-2015"], ["Mongo","12","23","15","22","43","05-02-2015"], ["Congo","15","32","21","23","44","06-02-2015"]];
var date, dataArray, dateIndex = (fields.length - 1),
dates = {};
for (var i = 0; i < values.length; i++) {
dataArray = values[i];
date = dataArray[dateIndex];
dates[date] = dates[date] || {};
for (j = 1; j < fields.length - 1; j++) {
dates[date][fields[j]] = dates[date][fields[j]] || 0;
dates[date][fields[j]] += Number(dataArray[j]);
}
}
console.log(dates);

Related

Filter one array using a 2nd array, and display the results on a spreadsheet

----- BACKGROUND ----- In Google Sheets/Apps Script, I'm trying to move some transaction data from one sheet and organize it on a different sheet with subtotal rows for each customer account (called "Units") with a grand total at the bottom.
I have the transactions organized in an array of objects as key:value pairs ("transactions", the keys are headers, some values are strings, others are numbers), and I have the units in a 2nd array called "unitList". I want to iterate through each element in the unitList array, and pull each transaction with a matching unit onto my "targetSheet", then append a subtotal row for each unit.
----- UPDATE 10/7/2018 3:49PM EST -----
Thanks to everyone for your input - I took your advice and ditched the library I was using and instead found better getRowsData and appendRowsData functions which I put directly in my code project. This fixed the array filter problem (verified by logging filterResults), BUT, now when I call appendRowsData(), I get this error:
The coordinates or dimensions of the range are invalid. (line 73, file "Display Transactions")
Line 73 is the line below, in the appendRowsData function. Any help on how to fix this would be greatly appreciated.
var destinationRange = sheet.getRange(firstDataRowIndex, 1, objects.length, 9);
Here's my project in it's entirety thus far:
function displayTransactions() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Label each sheet
var dashboard = ss.getSheetByName('Dashboard');
var unitsSheet = ss.getSheetByName('Unit Ref Table');
var transactionsSheet = ss.getSheetByName('Transactions Ref Sheet');
var targetSheet = ss.getSheetByName('Target Sheet');
// Returns true if the cell where cellData was read from is empty.
// Arguments:
// - cellData: string
function isCellEmpty(cellData) {
return typeof(cellData) == "string" && cellData == "";
}
// Define function that converts arrays into JSON
// For every row of data in data, generates an object that contains the data.
// Names of object fields are defined in keys.
// Arguments:
// - data: JavaScript 2d array
// - keys: Array of Strings that define the property names for the objects to create
function getObjects(data, keys) {
var objects = [];
for (var i = 0; i < data.length; ++i) {
var object = {};
var hasData = false;
for (var j = 0; j < data[i].length; ++j) {
var cellData = data[i][j];
if (isCellEmpty(cellData)) {
continue;
}
object[keys[j]] = cellData;
hasData = true;
}
if (hasData) {
objects.push(object);
}
}
return objects;
}
// Define function that pulls spreadsheet data into arrays, then converts to JSON using getObjects function
function getRowsData(sheet) {
var headersRange = sheet.getRange(1, 1, 1, sheet.getLastColumn());
var headers = headersRange.getValues()[0];
var dataRange = sheet.getRange(sheet.getFrozenRows()+1, 1, sheet.getLastRow(), sheet.getLastColumn());
return getObjects(dataRange.getValues(), headers);
}
// Define function appendRowsData that uses getLastRow to fill in one row of data per object defined in the objects array.
// For every Column, it checks if data objects define a value for it.
// Arguments:
// - sheet: the sheet object where the data will be written
// - objects: an array of objects, each of which contains data for a row
function appendRowsData(sheet, objects) {
var headersRange = sheet.getRange(7, 1, 1, 9);
var firstDataRowIndex = sheet.getLastRow() + 1;
var headers = headersRange.getValues()[0];
var data = [];
for (var i = 0; i < objects.length; ++i) {
var values = []
for (j = 0; j < headers.length; ++j) {
var header = headers[j];
values.push(header.length > 0 && objects[i][header] ? objects[i][header] : "");
}
data.push(values);
}
var destinationRange = sheet.getRange(firstDataRowIndex, 1, objects.length, 9);
destinationRange.setValues(data);
}
// Call getRowsData on transactions sheet
var transactions = getRowsData(transactionsSheet);
// Get array of units
var unitList = unitsSheet.getRange("B2:B").getValues();
// Iterate through the unitList and pull all transactions with matching unit into the target sheet
for (var i=0; i < unitList.length; i++) {
var subTotal = 0;
var grandTotal = 0;
var filterResults = transactions.filter(function(x) {
return x['Unit'] == unitList[i];
})
Logger.log(filterResults); // This brings the correct results!
// Display matching transactions
appendRowsData(targetSheet, filterResults);
// Grand total at the bottom when i=units.length
}
}

Google script, empty array from fetched API

I'm trying to fetch my ETH balance and transactions from etherscan.io website and I'm trying to use the same code I used before for another website. But it seems returning me an empty array, and also the error "The coordinates or dimensions of the range are invalid."
This is the code:
function getTx() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
var url = 'http://api.etherscan.io/api?module=account&action=txlist&address=0x49E81AA0cFE7eeA9738430212DC6677acF2f01a1&sort=asc';
var json = UrlFetchApp.fetch(url).getContentText();
var data = JSON.parse(json);
var rows = [],
array;
for (i = 0; i < data.length; i++) {
array = data[i];
rows.push([array.timeStamp, array.from, array.to, array.value]);
}
Logger.log(rows)
askRange = sheet.getRange(3, 1, rows.length, 3);
askRange.setValues(rows);
}
The logged "rows" is empty, what am I doing wrong?
Thank you
How about a following modification?
Modification points :
There is data you want at data.result.
Number of columns of data is 4.
Modified script :
function getTx() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
var url = 'http://api.etherscan.io/api?module=account&action=txlist&address=0x49E81AA0cFE7eeA9738430212DC6677acF2f01a1&sort=asc';
var json = UrlFetchApp.fetch(url).getContentText();
var data = JSON.parse(json);
var rows = [],
array;
for (i = 0; i < data.result.length; i++) { // Modified
array = data.result[i];
rows.push([array.timeStamp, array.from, array.to, array.value]);
}
Logger.log(rows)
askRange = sheet.getRange(3, 1, rows.length, 4); // Modified
askRange.setValues(rows);
}
If I misunderstand your question, I'm sorry.

How to delete the array with index 2 in local storage?

My local storage looks like this
{"data":[[0,"Post1","Text1","2016-12-16T11:01:00.000Z"],[1,"Post2","Text2","2016-12-20T14:00:00.000Z"]],[3,"Post3","Text3","2016-12-25T13:00:00.000Z"]]}
How can I delete only one item in the array?
I have tried with this, where postid is the array index I want to delete.
var postid = 1
var info = JSON.parse(localStorage.getItem("rp_data"));
var obj = [];
for(var i = 0; i < info.data.length; i++){
var data = info.data[i];
if(data === postid){
info.splice(i, 1);
}
}
localStorage.setItem("rp_data", JSON.stringify(data));
So the if part is wrong I guess!?
Any input appreciated, thanks.
UPDATE
So with this I can remove one of the posts in the array, where the first item in the array is equal to my postid, so if the postid=1 it will remove the second post in the array.
//var postid = $$(this).attr('data-id');
//postid=parseInt(postid)
postid=1
var info = JSON.parse(localStorage.getItem("rp_data"));
//remove object
for(var i = 0; i < info.data.length; i++){
var data = info.data[i][1];
myApp.alert(data);
if(i === postid){
myApp.alert(i);
info.data.splice(i, 1);
}
}
localStorage.removeItem("rp_data");
localStorage.setItem("rp_data", JSON.stringify(info));
So I have 1 more problems.
If I use postid=1 as above it works and it creates a new local storage with the right values. But if get the value from my form and then try to convert the string to a number it stops working.
This does not work, like it is not converting the string to a number?
var postid = $$(this).attr('data-id');
postid=parseInt(postid)
So why is this not converting it to a number?
Since the items in the array are JSON objects, you cannot compare the object to postid. You should use indexOf. You also don't want to splice the index. This should be the object or item in this case. If you want to remove the item in the object, you would have to iterate through the object as well. So this would be a nested loop.
//remove object
for(var i = 0; i < info.data.length; i++){
var data = info.data[i];
if(i === postid){
info.data.splice(data, 1);
}
}
//remove item in object
for(var i = 0; i < info.data.length; i++){
if(i == postid){
for(var j = 0; j < info.data[i].length; j++){
var item = info.data[i][j];
info.data[i].splice(item,1);
}
}
}

how to search for a specific word in a huge array?

In AS3 :
I've got a long text in an array.
var myHugeArray:Array = ["I love Apple
I have an Iphone
I eat a Banana
I'm John
I sell a computer
I sell an Apple
I love rock
I sell a car"];
How can I do to search a specifics words ? (like : show me sentences with the word "apple") --> output : "I love Apple" and "I sell an Apple"
Thanks,
EDIT
Here's what I did so far :
loader5.load(urlReq);
loader5.addEventListener(Event.COMPLETE,completeHandler2);
function completeHandler2(event:Event):void{
loader5.removeEventListener(Event.COMPLETE,completeHandler2);
trace("Données envoyées");
feedbackText.text = "Données envoyées";
loader5.load(urlReq);
loader5.addEventListener(Event.COMPLETE, complete);
}
function complete(e:Event):void {
addChild(list);
products = JSON.parse(loader5.data) as Array;
feedbackText.text = "complete";
for(var i:int = 0; i < products.length; i++){
createListItem(i, products[i]);
}
showList();
}
function createListItem(index:int, item:Object):void {
var listItem:TextField = new TextField();
listItem.text = item.title;
listItem.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void {
showDetails(item);
});
list.addChild(listItem);
str = item.title;
bar();
}
function bar(){
var arr: Array ;
searchBar.type = TextFieldType.INPUT;
var suggested:Array = new Array();
var textfields:Array = new Array();
searchBar.addEventListener(Event.CHANGE, suggest);
arr = str.split(",");
trace(arr);
function suggest(e:Event):void
{
suggested = [];
for (var i:int = 0; i < textfields.length; i++)
{
removeChild(textfields[i]);
}
textfields = [];
for (var j:int = 0; j < arr.length; j++)
{
if (arr[j].indexOf(searchBar.text.toLowerCase()) != -1)
{
var term:TextField = new TextField();
term.width = 360;
term.height = 24;
term.x = 18;
term.y = (24 * suggested.length) + 135;
term.border = true;
term.borderColor = 0x353535;
term.background = true;
term.backgroundColor = 0xFF9900;
term.textColor = 0x4C311D;
term.defaultTextFormat = format;
addChild(term);
suggested.push(arr[j]);
term.text = arr[j];
}
}
function showList():void {
list.visible = true;
}
function showDetails(item:Object):void {
titleTxt.htmlText = item.title;
detailsTxt.htmlText = "<U>prix:</U> " + item.prix + " xpf"+ "\n\n<U>Description:</U> " + "\n"+item.theDescription + "\n"+"\n\n<U>Contact:</U> " + item.mail+ "\n"+item.phone;
}
So, my AS3 code go search for PHP variable with loader5.
All the items found by the php are put in an Array (products).
And a list of all the products is created. (createListItem).
If I click on an item, it show me some details (price, description..etc). It's the function showDetails();
Know I've created a searchBar (autocomplete).
An array is created (arr) that split the string (str).
Then it does what it does to search through the array.
Problems :
1/ Weirdly, not all the words are displayed in my searchBar. Some words are working, other not.
2/ How can I do to call the function showDetails() when the user click on the suggest term ? (term.addEventListener(MouseEvent.CLICK, showDetails)); doesn't work as the terms is not item.title. ShowDetails is showing details of item.title. (so how can I say that term = item.title ?)
3/ Do you see a way simpler than that ?
Your myHugeArray is just string, so split() it with \n', you got the
ret array for example, then find the one contains the word you search, like "apple", using indexof() in each string
You need to split the string into an array then search each item
check this out
https://stackoverflow.com/a/34842518/3623547

Multidimensional Arrays and one of the fields

There is a multi-d array and I want to reach specific field in it. I have look around it but I was unable to find proper answer to my question.
My array is like that;
array-md
columns-- 0 | 1 | 2
index 0 - [1][John][Doe]
index 1 - [2][Sue][Allen]
index 2 - [3][Luiz][Guzman]
.
.
.
index n - [n+1][George][Smith]
My question is how can I reach only second column of the array? I tried name = array[loop][1]; but it says "Cannot access a property or method of a null object reference". What is the right way to do that?
Here is main part of the code.
get
var lpx:int;
var lpxi:int;
var arrLen:int = Info.endPageArray.length;
for(lpx = 0; lpx < arrLen; lpx++)
{
for(lpxi = Info.endPageArray[lpx][2]; lpxi < Info.endPageArray[lpx][1]; lpxi++)
{
if(Info._intervalSearch[lpxi] == "completed")
{
successCount++;
Info._unitIntervalSuccess.push([lpx, successCount / (Info._intervalSearch.length / 100)]);
}
}
}
set
for(lpix = 0; lpix < arrayLength; lpix++)
{
if(lpix + 1 <= arrayLength)
{
Info.endPageArray.push([lpix, Info._UnitsTriggers[lpix + 1], Info._UnitsTriggers[lpix]]);
}
else
{
Info.endPageArray.push([lpix, Info._UnitsTriggers[lpix], Info._UnitsTriggers[lpix - 1]]);
}
}
Try this:
var tempArr:Array = [];
function pushItem(itemName:String, itemSurname:String):void
{
var tempIndex:int = tempArr.length;
tempArr[tempIndex] = {};
tempArr[tempIndex][tempIndex + 1] = {};
tempArr[tempIndex][tempIndex + 1][name] = {};
tempArr[tempIndex][tempIndex + 1][name][itemSurname] = {};
}
function getNameObject(index:int):Object
{
var result:Object;
if(index < tempArr.length)
{
result = tempArr[index][index + 1];
}
return result;
}
pushItem("Max", "Payne");
pushItem("Lara", "Croft");
pushItem("Dart", "Vader");
//
trace(getNameObject(0));
trace(getNameObject(1));
trace(getNameObject(2));
Multidimensional array is an array of arrays, which you can create like this :
var persons:Array = [
['John', 'Doe'],
['Sue', 'Allen'],
['Luiz','Guzman']
];
var list:Array = [];
for(var i:int = 0; i < persons.length; i++)
{
list.push([i + 1, persons[i][0], persons[i][1]]);
}
trace(list);
// gives :
//
// 1, John, Doe
// 2, Sue, Allen
// 3, Luiz, Guzman
Then to get some data :
for(var j:int = 0; j < list.length; j++)
{
trace(list[j][1]); // gives for the 2nd line : Sue
}
For more about multidimensional arrays take a look here.
Hope that can help.

Resources