How to construct a 2D array - 2d

Newbie here, please teach me how to construct a 2D array.I tried but i still cant get it.
Table example :
I have "a", "b","c" as column name, and 100 row number.

$arr = [0 => ['a', 'b', 'c'], 1 => ['a', 'b', 'c'], 2 => ['a', 'b', 'c']];
0, 1, 2 are rows
a, b, c are columns
Also check out array_map without the first parameter
http://php.net/manual/en/function.array-map.php#example-5081

Related

why does pushing an array onto an array give an array within an array within an array

In JavaScript, when I push an array onto an array, I seem to get an extra level of indirection. That is, there seems to be an array within an array within an array - at least according to the Google Apps Script debugger. I'm trying to end of with a three dimensional array, but I require 4 indexes to get the length of the inner most array. Does this make sense to anybody?
In JavaScript, push inserts the element or object as the last item of the array regardless of how many elements it contains. In array1 below, "c" occupies the last position. Its index is 2. When we array1.push(array2), array2 is moved into index 3 of array 1:
let array1 = ["a", "b", "c"];
let array2 = [1, 2, 3];
array1.push(array2);
console.log(array1); # result: [ 'a', 'b', 'c', [ 1, 2, 3 ] ]
As Hadar C said, use concat(), instead:
let array3 = ["a", "b", "c"];
let array4 = [1, 2, 3];
array3 = array3.concat(array4); # result: [ 'a', 'b', 'c', 1, 2, 3 ]

Is there a way to find if a sequence of two chars are found in a list only if they are consecutive?

I am currently working in the elm syntax. An example would be like this:
(Sequence ('a') ('b')) ('c') ['a', 'b', 'c', 'd'] . In this example, i only test if the elements 'a', 'b', 'c' are members of the list. If yes, then i partition it and obtain (['a','b','c'],['d'])
I encountered problems in the following case:
(Sequence ('a') ('b')) ('c') ['a', 'b', 'c', 'a']
obtaining the result :
(['a','b','c','a'],[])
My question is: what condition should i put such that the elements 'a' and 'b' must be consecutive avoiding the case when they are matched alone?
This answer assumes that if you have Sequence 'a' 'b' 'c' and test it against the list ['a', 'b', 'c', 'a'], you want to receive the result (['a', 'b', 'c'], ['a']) (as asked in this comment).
In pseudo-code:
Split the list into two, list1 and list2. list1 should have the same length as your sequence. Elm provides List.take and List.drop for that
Convert your sequence into a list list_sequence with a helper function
Test if list1 and list_sequence are equal
If they are, return the tuple (list1, list2)
And here is the actual Elm code:
https://ellie-app.com/bjBLns4dKkra1
Here is some code that tests if a sequence of elements occurs in a list:
module Main exposing (main)
import Html exposing (Html, text)
containsSeq : List a -> List a -> Bool
containsSeq seq list =
let
helper remainingSeq remainingList savedSeq savedList =
case remainingSeq of
[] ->
True
x :: xs ->
case remainingList of
[] ->
False
y :: ys ->
if x == y then
helper xs ys (savedSeq ++ [ x ]) (savedList ++ [ y ])
else
case savedList of
[] ->
helper (savedSeq ++ remainingSeq) ys [] []
y2 :: y2s ->
helper (savedSeq ++ remainingSeq) (y2s ++ remainingList) [] []
in
helper seq list [] []
main =
text <| Debug.toString <| containsSeq [ 'a', 'b', 'c' ] [ 'a', 'b', 'a', 'b', 'c', 'd' ]
This only checks if the sequences appears and the type of the elements have to be comparable.
Here is the above function altered to return a partitioning of the old list as a 3 elements Tuple with (elementsBefore, sequence, elementsAfter). The result is wrapped in a Maybe so that if the sequence is not found, it returns Nothing.
module Main exposing (main)
import Html exposing (Html, text)
partitionBySeq : List a -> List a -> Maybe ( List a, List a, List a )
partitionBySeq seq list =
let
helper remainingSeq remainingList savedSeq savedCurrentList savedOldList =
case remainingSeq of
[] ->
Just ( savedOldList, seq, remainingList )
x :: xs ->
case remainingList of
[] ->
Nothing
y :: ys ->
if x == y then
helper xs ys (savedSeq ++ [ x ]) (savedCurrentList ++ [ y ]) savedOldList
else
case savedCurrentList of
[] ->
helper (savedSeq ++ remainingSeq) ys [] [] (savedOldList ++ [ y ])
y2 :: y2s ->
helper (savedSeq ++ remainingSeq) (y2s ++ remainingList) [] [] (savedOldList ++ [ y ])
in
helper seq list [] [] []
main =
text <| Debug.toString <| partitionBySeq [ 'a', 'b', 'c' ] [ 'a', 'b', 'a', 'b', 'c', 'd' ]
Of course, if you are only dealing with characters, you might as well convert the list into a String using String.fromList and use String.contains "abc" "ababcd" for the first version and String.split "abc" "ababcd" to implement the second one.

Broadcasting algebraic operations between dicts

I have two dicts and I want to subtract the matching values from the two dicts to generate a third dict.
A = Dict("w" => 2, "x" => 3)
B = Dict("x" => 5, "w" => 7)
# Ideally I could go B .- A and get a dict like
C = Dict("w" => 5, "x" => 2)
# but I get ERROR: ArgumentError: broadcasting over dictionaries and `NamedTuple`s is reserved
One ugly solution is to overload the subtraction operator but I am not keen to overload for a builtin type like dict for fear of breaking other code.
import Base.-
function -(dictA::Dict, dictB::Dict)
keys_of_A = keys(dictA)
subtractions = get.(Ref(dictB), keys_of_A, 0) .- get.(Ref(dictA), keys_of_A, 0)
return Dict(keys_of_A .=> subtractions)
end
Is there a cleaner way to do algebraic operations on matching values from different dicts?
merge provides the result you want.
A = Dict("w" => 2, "x" => 3)
B = Dict("x" => 5, "w" => 7)
C = merge(-, B, A)
Dict{String,Int64} with 2 entries:
"w" => 5
"x" => 2
Note that merge performs a union of the two collections and combines common keys by performing the given operation. So, for example:
W = Dict("w" => 4)
merge(-, B, W)
Dict{String,Int64} with 2 entries:
"w" => 3
"x" => 5

Getting second and third highest value in a dictionary

dict = {'a':5 , 'b':4, 'c':3, 'd':3, 'e':1}
Second is 'b' with 4 times. Joint third are 'c' and 'd' with 3 times. As the dictionary changes over time, say, 'f' is added with a value of 3, then third will be 'c', 'd', and 'f' with 3 times.
just create a gencomp of tuple value,key and sort it. Print items
d = {'a':5 , 'b':4, 'c':3, 'd':3, 'e':1}
x = sorted(((v,k) for k,v in d.items()))
print(x[-2][1])
print(x[-3][1])
result:
b
d
(would fail if dict doesn't have at least 3 items)
Or directly with key parameter (avoids data reordering)
x = sorted(d.items(),key=(lambda i: i[1]))
print(x[-2][0])
print(x[-3][0])
result:
b
d
BTW avoid using dict as a variable.
EDIT: since there are several identical values, you may want to get the 2 second best values and the associated letters. You have to do it differently. I'd create a default list using key as value and store in a list, then sort it as done in the above code:
import collections
d = {'a':5 , 'b':4, 'c':3, 'd':3, 'e':1}
dd = collections.defaultdict(list)
for k,v in d.items():
dd[v].append(k)
x = sorted(dd.items())
print(x[-2])
print(x[-3])
result:
(4, ['b'])
(3, ['c', 'd'])

Appending data to an AT Field using transmogrifier

I have a CSV file of data like this:
1, [a, b, c]
2, [a, b, d]
3, [a]
and some Plone objects which should be updated like this:
ID, LinesField
a, [1,2,3]
b, [1,2]
c, [1]
d, [2]
So, to clarify, the object with the id a is named on lines 1, 2 and 3 of the CSV, and thus the LinesField property of object a needs to have those line ids (the first number on the line) listed.
Ideally I'd like to use Transmogrifier to import this information (and avoid doing any manipulation in Excel beforehand), and I can see two ways, theoretically of doing this, but I can't work out how to do this in practice. I'd be grateful for some pointers to examples. I think that either I need to transform the entire pipeline so that the items reflect the structure of my Plone objects and then use the ATSchemaUpdater blueprint, but I can't see any examples on how to add items to the pipeline (do I need to write my own blueprint?) Or, alternatively I could loop through the items as they exist and append the value in the left column to the items in the list in the right. For that I need a way of appending values with ATSchemaUpdater rather than overwriting them - again, is there a blueprint for that anywhere?
Here's a few sample csv lines:
"Name","Themes"
"Bessie Brown","cah;cab;cac"
"Fred Blogs","cah;cac"
"Dinah Washington","cah;cab"
The Plone object will be a theme and the lines field a list of names:
cah, ['Bessie Brown', 'Fred Boggs' etc etc]
I'm not pretty sure you want to read the CVS file using transmogrifier, but I think you can create a section to insert these values to the items in the pipeline using a function like this:
def transpose(cvs):
keys = []
[keys.extend(v) for v in cvs.values()]
keys = set(keys)
d = {}
for key in keys:
values = [k for k, v in cvs.iteritems() if key in v]
d[key] = values
return d
In this context, cvs is {1: ['a', 'b', 'c'], 2: ['a', 'b', 'd'], 3: ['a']}; keys will contain all possible values set(['a', 'c', 'b', 'd']); and d will be what you want {'a': [1, 2, 3], 'c': [1], 'b': [1, 2], 'd': [2]}.
Probably there are better ways to do it, but I'm not a Python magician.
The insert section could look like this one:
class Insert(object):
"""Insert new keys into items.
"""
classProvides(ISectionBlueprint)
implements(ISection)
def __init__(self, transmogrifier, name, options, previous):
self.previous = previous
self.new_keys = transpose(cvs)
def __iter__(self):
for item in self.previous:
item.update(self.new_keys)
yield item
After that you can use the SchemaUpdater section.

Resources