swift3 - print array index to each row - swift3

how do you print out the index of an array to a tableview cell?
for example:
var list = [Person]()
I have this array of objects and I add each object to the tableview like so:
cell.nameLabel?.text = list[indexPath.row].firstName + " , " + list[indexPath.row].lastName
but I also want to print the index for each item next to the first and last name. For example, if the array has ["mike jones", "James smith"], it would look like this:
1 mike jones
2 James smith
it would be stored in this positionLabel
//cell.positionLabel?.text = list[indexPath.row]

let person = list[indexPath.row]
cell.nameLabel?.text = "\(indexPath.row) \(person.firstName) \(person.lastName)"

Related

Google Script: Match RegEx into 2D array

I'm trying to extract information from Gmail into Google Spreadsheet. The information in the email has a table structure with the following columns List of Products, QTY Sold and the Subtotal for each product. These repeat N times.
When accesing the information using message.getPlainBody() I get the following text:
Product
Quantity
Price
Chocolate
1
$8.58
Apples
2
$40.40
Bananas
1
$95.99
Candy
1
$4.99
Subtotal:
$149.96
Progress
First I tried to use a regular expression to identify each row with all his elements:
Product name: Any amount of characters that don't include ':' (.*)[^:]
QTY Sold: Any number \d*
Anything that looks like a SubTotal [$]\d*.\d*
Wrapping everything up it looks like this
function ExtractDetail(message){
var mainbody = message.getPlainBody();
//RegEx
var itemListRegex = new RegExp(/(.*)[^:][\r\n]+(\d*[\r\n]+[$](\d*\.\d*)[\r\n]+/g);
var itemList = mainbody.match(itemListRegex);
Logger.log(itemList);
}
And so far it works:
itemList: Chocolate 1 $8.58 ,Apples 2 $40.40 ,Bananas 1 $95.99
,Candy 1 $4.99
However, I'm getting the following result:
[Chocolate 1 $8.58]
[Apples 2 $40.40]
[Bananas 1 $95.99]
[Candy 1 $4.99]
Instead of:
[Chocolate] [ 1 ] [$8.58]
[Apples] [ 2 ] [$40.40]
[Bananas] [ 1 ] [$95.99]
[Candy] [ 1 ] [$4.99]
Question
My question is, how can I append a new row in a way that it each row corresponds to each match found and that each column corresponds to each property?
How do I turn the result of each match into an array? Is it possible or should I change my approach?
Update:
Since the result of my current attemp is a large string I'm trying to find other options. This one poped up:
var array = Array.from(mainbody.matchAll(itemListRegex), m => m[1]);
Source: How do you access the matched groups in a JavaScript regular expression?
I'm still working on it. I still need to find how to add more columns and for some reason it starts on 'Apples' (following the examples), leaving 'Chocolates' behind.
Log:
Logger.log('array: ' + array);
If you want to use matchAll like Array.from(mainbody.matchAll(itemListRegex), m => m[1]), how about this modification?
In this case, /(.*[^:])[\r\n]+(\d*)[\r\n]+([$]\d*\.\d*)[\r\n]/g is used as the regex.
Modified script:
const itemListRegex = /(.*[^:])[\r\n]+(\d*)[\r\n]+([$]\d*\.\d*)[\r\n]/g;
var array = Array.from(mainbody.matchAll(itemListRegex), ([,b,c,d]) => [b,Number(c),d]);
Result:
[
["Chocolate",1,"$8.58"],
["Apples",2,"$40.40"],
["Bananas",1,"$95.99"],
["Candy",1,"$4.99"]
]
The result is the same with TheMaster's answer.
Test of script:
const mainbody = `
Product
Quantity
Price
Chocolate
1
$8.58
Apples
2
$40.40
Bananas
1
$95.99
Candy
1
$4.99
Subtotal:
$149.96
`;
const itemListRegex = /(.*[^:])[\r\n]+(\d*)[\r\n]+([$]\d*\.\d*)[\r\n]/g;
var array = Array.from(mainbody.matchAll(itemListRegex), ([,b,c,d]) => [b,Number(c),d]);
console.log(array)
Note:
About how can I append a new row in a way that it each row corresponds to each match found and that each column corresponds to each property?, this means for putting the values to Spreadsheet? If it's so, can you provide a sample result you expect?
References:
matchAll()
Array.from()
Map and split the resulting array by \new lines:
const data = `Product
Quantity
Price
Chocolate
1
$8.58
Apples
2
$40.40
Bananas
1
$95.99
Candy
1
$4.99
Subtotal:
$149.96`;
const itemListRegex = /.*[^:][\r\n]+\d*[\r\n]+\$\d*\.\d*(?=[\r\n]+)/g;
const itemList = data.match(itemListRegex);
console.info(itemList.map(e => e.split(/\n/)));//map and split

Google Sheets Search and Sum in two lists

I have a Google Sheets question I was hoping someone could help with.
I have a list of about 200 keywords which looks like the ones below:
**List 1**
Italy City trip
Italy Roundtrip
Italy Holiday
Hungary City trip
Czechia City trip
Croatia Montenegro Roundtrip
....
....
And I then have another list with jumbled keywords with around 1 million rows. The keywords in this list don't exactly match with the first list. What I need to do is search for the keywords in list 1 (above) in list 2 (below) and sum all corresponding cost values. As you can see in the list below the keywords from list 1 are in the second list but with other keywords around them. For example, I need a formula that will search for "Italy City trip" from list 1, in list 2 and sum the cost when that keyword occurs. In this case, it would be 6 total. Adding the cost of "Italy City trip April" and "Italy City trip June" together.
**List 2** Cost
Italy City trip April 1
Italy City trip June 5
Next week Italy Roundtrip 4
Italy Holiday next week 1
Hungary City holiday trip 9
....
....
I hope that makes sense.
Any help would be greatly appreciated
try:
=ARRAYFORMULA(QUERY({IFNA(REGEXEXTRACT(PROPER(C1:C),
TEXTJOIN("|", 1, SORT(PROPER(A1:A), 1, 0)))), D1:D},
"select Col1,sum(Col2)
where Col1 is not null
group by Col1
label sum(Col2)''", 0))
You want to establish whether keywords in one list (List#1) can be found in another list (List#2).
List#2 is 1,000,000 rows long, so I would recommend segmenting the list so that execution times are not exceeded. That's something you will be able to establish by trial and error.
The solution is to use the javascript method indexOf.
Paraphrasing from w3schools: indexOf() returns the position of the first occurrence of a specified value in a string. If the value is not found, it returns -1. So testing if (idx !=-1){ will only return List#1 values that were found in List#2. Note: The indexOf() method is case sensitive.
function so5864274503() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var srcname = "source";
var tgtname = "target";
var sourceSheet = ss.getSheetByName(srcname);
var targetSheet = ss.getSheetByName(tgtname);
// get the source list
var sourceLR = sourceSheet.getLastRow();
var srcData = sourceSheet.getRange(1,1,sourceLR).getValues();
//get the target list
var targetLR = targetSheet.getLastRow();
var tgtlist = targetSheet.getRange(1,1,targetLR,2).getValues();
var totalcostvalues = [];
// start looping through the keywords (list 1)
for (var s = 0;s<srcData.length;s++){
var totalcost = 0;
var value = srcData[s][0]
// start looping through the strings (List 2)
for (var i=0;i<tgtlist.length;i++){
// set cost to zero
var cumcost = 0;
// use indexOf to test if keyword is in the string
var idx = tgtlist[i][0].indexOf(value);
// value of -1 = no match, value >-1 indicates posuton in the string where the key word was found
if (idx !=-1){
var cost = tgtlist[i][1]
cumcost = cumcost + cost;
totalcost = totalcost+cost
}
}//end of loop - list2
//Logger.log("DEBUG: Summary: "+value+", totalcost = "+totalcost)
totalcostvalues.push([totalcost])
}// end of loop - list1
//Logger.log(totalcostvalues); //DEBUG
sourceSheet.getRange(1,2,sourceLR).setValues(totalcostvalues);
}
I also got this one, but it's case sensitive a bit
function myFunction() {
var ss = SpreadsheetApp.getActive();
var sheet1 = ss.getSheets()[0];
var sheet2 = ss.getSheets()[1];
var valuesSheet1 = sheet1.getRange(2,1, (sheet1.getLastRow()-1), sheet1.getLastColumn()).getValues();
var valuesCol1Sheet1 = valuesSheet1.map(function(r){return r[0]});
var valuesCol2Sheet1 = valuesSheet1.map(function(r){return r[1]});
Logger.log(valuesCol2Sheet1);
var valuesSheet2 = sheet2.getRange(2,1, (sheet2.getLastRow()-1)).getValues();
var valuesCol1Sheet2 = valuesSheet2.map(function(r){return r[0]});
for (var i = 0; i<= valuesCol1Sheet2.length-1; i++){
var price = 0;
valuesCol1Sheet1.forEach(function(elt,index){
var position = elt.toLowerCase().indexOf(valuesCol1Sheet2[i].toLowerCase());
if(position >-1){
price = price + valuesCol2Sheet1[index];
}
});
sheet2.getRange((i+2),2).setValue(price);
};
}

How to split list of strings into two columns and append it to a spire pdf in c#

This is my list of data type string:
List<string> Questions = new List<string>();
I am appending list of static questions ,answers to the question values from model
Questions .Add("Q1? " + " : " + model.value);
Questions .Add("Q2?" + " : " + model.value);
string[][] datasource = new String[Questions .Count][];
for (int i = 0; i < Questions .Count; i++)
{
datasource[i] = Questions [i].Split(';');
}
Appending it to spire pdf table:
PdfTable table = new PdfTable();
table.DataSource = datasource;
MY output:
What type of tax return does the entity file? : 604 --In single column
Expected output:
column1 column2
What type of tax return does the entity file? 604
Kindly note that there's only one set of data in every element of the array "Questions", thus the table only has a single column. If you want the expected output of two columns, please change your code as:
string[] Questions = { "Q1?:;model.value", "Q2?:;model.value" };

How do i extract specific characters from elements in a list in python?

['PRE user_1/\n', '2016-11-30 11:43:32 62944 UserID-12345.jpg\n', '2016-11-28 10:07:24 29227 anpr.jpg\n', '2016-11-30 11:38:30 62944 image.jpg\n']
I have a list of string and i want to extract the 'name\n' part from each element and store it. For example i want to extract 'name\n' from mylist[0], where mylist[0] = 'PRE user_/n'. So user_1/ will be extracted and stored in a variable.
mylist = ['PRE user_1/\n', '2016-11-30 11:43:32 62944 UserID-12345.jpg\n', '2016-11-28 10:07:24 29227 anpr.jpg\n', '2016-11-30 11:38:30 62944 image.jpg\n']
for x in mylist:
i = 0
userid = *extract the 'name\n' from mylist[i]
print userid
i = i+1
How do i do this? Is Regular Expressions the way to do it?, if yes how do i implement it? A code snippet would be very helpful.
Maybe you can do it without regex. You can try my solution:
a = ['PRE user_1/\n', '2016-11-30 11:43:32 62944 UserID-12345.jpg\n', '2016-11-28 10:07:24 29227 anpr.jpg\n', '2016-11-30 11:38:30 62944 image.jpg\n']
def get_name(arg = ""):
b = arg.split(" ")
for i in b:
if "\n" in i:
return i.replace("\n", "")
Output:
print get_name(a[0])
user_1/
print get_name(a[1])
UserID-12345.jpg
print get_name(a[2])
anpr.jpg
print get_name(a[3])
image.jpg
Also in order to fill the example you gave, your code will be:
for x in a:
userid = get_name(x)
print userid
Output:
user_1/
UserID-12345.jpg
anpr.jpg
image.jpg

Taking First Two Elements in List

I am trying to script a dynamic way way to only take the first two elements in a list and I am having some trouble. Below is a breakdown of what I have in my List
Declaration:
Set List = CreateObject("Scripting.Dictionary")
List Contents:
List(0) = 0-0-0-0
List(1) = 0-1-0-0
List(2) = 0-2-0-0
Code so far:
for count = 0 To UBound(List) -1 step 1
//not sure how to return
next
What I currently have does not work.
Desired Return List:
0-0-0-0
0-1-0-0
You need to use the Items method of the Dictionary. For more info see here
For example:
Dim a, i
a = List.Items
For i = 0 To List.Count - 1
MsgBox(a(i))
Next i
or if you just want the first 2:
For i = 0 To 1
MsgBox(a(i))
Next i
UBound() is for arrays, not dictionaries. You need to use the Count property of the Dictionary object.
' Show all dictionary items...
For i = 0 To List.Count - 1
MsgBox List(i)
Next
' Show the first two dictionary items...
For i = 0 To 1
MsgBox List(i)
Next