Match and do nothing if already exist - arrays

I need some help again please.
I am trying to create a list of items which I am calling from an Excel spreadsheet.
Let's say that columns A holds a list of countries.
America
South Africa
Belgium
America
Now there are other items attached to the countries in the corresponding row, but at column D, so there might be more items in other columns that correspond to the country in the first cell, like this.
______________A__________________________B___________________C___________
---------------|----------------|-------------|
America........|..Samsung.......|...1234......|
South Africa...|..Dell..........|...54321.....|
Belgium........|..iPhone........|...2345......|
America........|..Nokia.........|...9876......|
I want to publish this to an XML sheet, but I do not want to create each country more than once, so I want to check the row for entry and if it does not exist, create it. So in the table above, I have America twice, but it needs to create America once only as an XML entry and from there I will attach the other items.
For now I am getting the row data by counting the rows in the sheet as it will differ each time, then I need to start writing XML.
use Spreadsheet::Read;
#use XML::Writer
my $book = ReadData("InfoDB.xlsx");
my #rows = Spreadsheet::Read::rows($book->[1]);
my $count = 1;
my #clause_all;
foreach $tab (#rows) {
$count++;
#row = Spreadsheet::Read::cellrow($book->[1], $count);
#country = $row[1];
}
If anyone can please help me with matching this into an array or somehow it would be great!
I tried a whole lot of methods but cannot get a perfect result, I would actually bore you if I posted each try I attempted. :(

Create a hash, use the country name as keys:
Then push your new data onto an array reference stored at that key - this is psuedocode. You'll need to sprinkle in the spreadsheet madness to make it work.
%countries = ();
foreach my $row ( #rows) {
my ($country, $thing, $number) = row2columns($row);
push #{ $countries{$country} }, [ $thing, $number ];
}
now you have a big hash that you can convert to XML in your preferred manner.

Something along the lines of:
my #country;
foreach my $tab (#rows) {
...
# The smart match operator (~~) will return true if the value on the
# left is found in the list on the right.
unless ($row[1] ~~ #country) {
# do the things you need to do then add the country to the list
push #country, $row[1];
}
}

Related

Is it necessary to avoid loops for updating models in laravel?

I'm trying to sort multiple records for a model based on a field and store their ranks in DB. Like below:
$instances = Model::orderBy('field')->get();
$rank = 1;
foreach ($instances as $instance) {
$instance->update([
'rank' => $rank,
]);
$rank++;
}
I have two questions:
1- Is there any alternative ways to avoid using loop? for example I put the ranks in an array and update the whole records by only one magic method. For example:
$instances = Model::orderBy('field')->get();
$rank = 1;
$ranks_array = array();
foreach ($instances as $instance) {
array_push($ranks_array, $rank);
$rank++;
}
$instances->magicMethod($ranks_array);
2- Is it necessary at all to do so? are the loops have heavy effects on the server or not? need to say that the number of records I'm going to update may not exceed 50 at all.
For insert queries, inserting all records at once will go much faster than inserting them one by one. However for update queries, if you need to update specific rows with specific data, there is no other way than to update them one by one.
I recently came across a similar issue where I needed to update 90k+ row from my DB.
Because I needed to add specific values to each column I needed to individually update each column.
What I found was instead of doing
$DBModel = Model::get();
foreach ($DBModel as $row) {
$row->notify = $row->paid;
// the date is calculated from a specific carbon date from another column
// I did not include the logic here for the example
$row->due = "0000-00-00 00:00:00";
$row->save();
}
Running the previous query took 5m33s
But doing it like this
$DBModel = Model::get();
DB::beginTransaction();
foreach ($DBModel as $row) {
DB::update(update TABLE_NAME set due = ?, notify = ? where id = ?",
["0000-00-00 00:00:00", $row->paid, $row->id]
);
}
DB::commit();
The previous query took only 1m54s to execute.

database design eloquent problem with query

I need to create an app who manage soccer sheets
I have actually a table who store the match with both teams
match :
-id
-dt_math
-club_home_id
-club_visitor_id
each team have a sheet to create the list of players.
So what i did, i created table match_sheet to store the both sheets from the teams.
match_sheet :
-id
-match_id
to store the players in each sheets i created the table match_sheet_player
match_sheet_player:
-id
-match_sheet_id
-player_id
Now i need to display only the matchs who have the both sheets in my view. and i don't know how to achieve that.
The first query that i made is that :
$matchs_sheets = MatchSheet::all();
$matchs = Match::whereIn('id', $matchs_sheets->pluck('match_id'))->orderByDesc('dt_match')->paginate(5);
But this return my the match even if there is one sheet but not both sheets. i really need to show the match onyl if there is the two sheets.
Update :
here my data for math_sheet
there is two records with 1659. 1659 is the id of the match. so i would like to only show match 1659 and not 1649 because there is only one record for this match
Assuming your model relationships are set up correctly, you can ask Laravel to get the matches only if the related model has a count of at least 2, using has(). For instance:
$matches = Match::whereIn('id', $ids)->has('matchSheet', '=', 2)...
Your relationship should be set up as e.g. this:
// on Match model
public function matchSheets()
{
return $this->hasMany(MatchSheet::class);
}
// on MatchSheet model
public function match()
{
return $this->belongsTo(Match::class);
}
Docs here: https://laravel.com/docs/5.6/eloquent-relationships#one-to-many - I really recommend reading through them, they'll save you huge amounts of time eventually!

Contact form is changing order of form data

I have a contact form that uses a CGI script to get form data and send through email. The script works fine except for the fact that it seems to change the order of form elements. I think I have pinpointed the block of code responsible for this.
Is there a way to alter this so that it sends the form data as-is, without re-ordering?
sub get_data {
use CGI qw/:standard/;
my $query = new CGI;
foreach $key ($query->param()){
$data{$key} = $query->param($key);
}
%data; # return associative array of name=value
}
From perldoc CGI
If the script was invoked with a parameter list (e.g. "name1=value1&name2=value2&name3=value3"), the param() method will return the parameter names as a list. If the script was invoked as an script and contains a string without ampersands (e.g. "value1+value2+value3") , there will be a single parameter named "keywords" containing the "+"-delimited keywords.
NOTE: As of version 1.5, the array of parameter names returned will be in the same order as they were submitted by the browser. Usually this order is the same as the order in which the parameters are defined in the form (however, this isn't part of the spec, and so isn't guaranteed).
So you can keep order of keys by storing them in array,
my #ordered = $query->param();
or don't use hash at all,
my #data;
foreach $key ($query->param()){
push #data, [ $key, $query->param($key) ];
}
return #data;
Well, you're putting your parameters into a hash. And hashes have no intrinsic ordering. The only way to get key/value pairs out for a hash in the same order as you put them in, is to keep a separate array containing the order of the keys.
Do you really need the parameters in a hash? Can't you just use your foreach loop at the point when you're creating the email?

CakePHP How do I display all table field names

New to CakePHP, so be gentle...
I'm trying to loop through a table to display all the read-only fields (labels and values).
In my edit function, I get the table
$this->set('invoice', $this->Invoice->read(null, $id));
In my view, I want to loop through the entire table schema and output the field names and values as labels like fieldName: value
Invoice Number: SVC00158
Invoice Date: 03/03/12
There are 37 fields in this table. I would rather not have to manually code for every one. I know to retrieve the input fields like this
echo $this->Form->input('purchaseOrderNumber');
but I can't seem to find a 'read-only' attribute for the input() method. Hope that makes sense.
Thanks for your time.
You could loop through the schema and output it like that:
// assumes $result contains model data
$schema = $this->Model->schema();
foreach ($schema as $field => $attrs) {
echo $result['Model'][$field];
}
just write:
<?=$this->Form->inputs();?>
If you are a beginner I suggest you look into Cake Bake (it will "bake" all your files from the console).
I mean the views, controllers, and models based on you current db schema so that will it for you and even apply some styling to it.
I hope that helps

Linq to SQL Records where child ID in list

I have a site where I have a database of persons and each person can have multiple intrests which is handled through a one to many relationship between a persons table and an interests table. On the site I want to have a serach where you can have a multiple select box of interests and the user can pick as many as they want. What I want to return is a record set of all persons who have any interests contained in the selected options. My code is C# asp.net and looks something like this so far:
personResults = (from p in data.Persons
orderby p.lastName, p.firstName
select p);
And I want to add something like this although I know the last line in the following code is totally bogus. Assume that interests is my multiple select box ID.
List<int> interestIdList = new List<int>();
if (interest.GetSelectedIndices().Length > 0) {
foreach(int selectedIndex in interest.GetSelectedIndices()){
interestIdList.Add(int.Parse(interest.Items[selectedIndex].Value));
}
personResults = personResults.Where(x => interestIdList.Contains(x.Interests[].interestID));
}
The problem is that last line of code. Because x.Interests is a collection of interest objects out of the database I can't access their interestID (how does the code now which interest items ID to access if a person has 5 interests). If it will help I can use my list of interest ID's to build a list of interest objects but I still cant figure out how to build the query.
Again to state my goal I want any person who has an interest where the interest ID is in the interestIdList array. They do not all have to match; as long as there is at least one common value I want the record.
If the appropriate relations from the persons table to the "personsWithInterests" table to the interests table is set up in the DBML, you can try this:
ArrayList ids = new ArrayList();
foreach (int index in interest.GetSelectedIndices())
{
ids.Add(interest.Items[index].Value);
}
string[] idArray = (string[])ids.ToArray(typeof(string));
var personsWithInterests = (from pi in data.PersonInterests where idArray.Contains(pi.Interest.Id.ToString()) select pi.Person).Distinct();

Resources