document.querySelectorAll get innerText of ALL selected elements at once pure javascript - element

I want to get all innerText of a whole column of a very long html table (random length).
I'm using this code:
var tbEls = document.querySelectorAll('#tBodyID tr td:nth-child(cidx)');
Where cidx = the column index I want to extract content from.
But such code extracts all the td elements (with the innerText inside them of course).
But it doesn't extract directly all the innerText inside them. Cause of this I have to reprocess the returned tdEls array with a for loop to extract from each tbEls[i] element its own innerText. It works but...
My question is:
In pure JS (no external libraries or frameworks) is it possible to use a more direct approach improving some way just and only the querySelectorAll parameter ('#tBodyID tr td:nth-child(cidx)') to get directly all the td elements innerText at once and in just one javascript statement and without the need of reprocessing the returned array with the for loop or anything else?
In other words is there a some kind of innerText selector that can be used to get them all at once without any kind of extra loop?
No problem at all if it is not recognized by old browsers, I'm sorry for them.
What I hope to achieve is something like:
var arrTblColInnerText = document.querySelectorAll('#tBodyID tr td:nth-child(cidx):alltd:innerText');
I want to get an array similar to:
0: value from column cidx cell 0
1: value from column cidx cell 1
2: value from column cidx cell 2
3: value from column cidx cell 3
...
n: value from column cidx cell n
Thanks in advance.

The easiest way I found was to convert the nodeList to an array first then use a map:
var nodes = document.querySelectorAll("h3 em");
var list = [].slice.call(nodes);
var innertext = list.map(function(e) { return e.innerText; }).join("\n");

Here's a one-liner from 2021. It says to take the NodeList returned from the querySelectorAll and make it an Array, then map the innerText into an array.
Array.from(document.querySelectorAll("h3 em")).map(x => x.innerText)

Related

Create structure fieldnames from array of numbers

I have a dataset that I would like to categorise and store in a structure based on the value in one column of the dataset. For example, the data can be categorised into element 'label_100', 'label_200' or 'label_300' as I attempt below:
%The labels I would like are based on the dataset
example_data = [repmat(100,1,100),repmat(200,1,100),repmat(300,1,100)];
data_names = unique(example_data);
%create a cell array of strings for the structure fieldnames
for i = 1:length(data_names)
cell_data_names{i}=sprintf('label_%d', data_names(i));
end
%create a cell array of data (just 0's for now)
others = num2cell(zeros(size(cell_data_names)));
%try and create the structure
data = struct(cell_data_names{:},others{:})
This fails and I get the following error message:
"Error using struct
Field names must be strings."
(Also, is there a more direct method to achieve what I am trying to do above?)
According to the documentation of struct,
S = struct('field1',VALUES1,'field2',VALUES2,...) creates a
structure array with the specified fields and values.
So you need to have each value right after its field name. The way you are calling struct now is
S = struct('field1','field2',VALUES1,VALUES2,...)
instead of the correct
S = struct('field1',VALUES1,'field2',VALUES2,...).
You can solve that by concatenating cell_data_names and others vertically and then using {:} to produce a comma-separated list. This will give the cells' contents in column-major order, so each field name fill be immediately followed by the corresponding value:
cell_data_names_others = [cell_data_names; others]
data = struct(cell_data_names_others{:})

Scala create array of empty arrays

I am trying to create an array where each element is an empty array.
I have tried this:
var result = Array.fill[Array[Int]](Array.empty[Int])
After looking here How to create and use a multi-dimensional array in Scala?, I also tried this:
var result = Array.ofDim[Array[Int]](Array.empty[Int])
However, none of these work.
How can I create an array of empty arrays?
You are misunderstanding Array.ofDim here. It creates a multidimensional array given the dimensions and the type of value to hold.
To create an array of 100 arrays, each of which is empty (0 elements) and would hold Ints, you need only to specify those dimensions as parameters to the ofDim function.
val result = Array.ofDim[Int](100, 0)
Array.fill takes two params: The first is the length, the second the value to fill the array with, more precisely the second parameter is an element computation that will be invoked multiple times to obtain the array elements (Thanks to #alexey-romanov for pointing this out). However, in your case it results always in the same value, the empty array.
Array.fill[Array[Int]](length)(Array.empty)
Consider also Array.tabulate as follows,
val result = Array.tabulate(100)(_ => Array[Int]())
where the lambda function is applied 100 times and for each it delivers an empty array.

How to pass selected Gtk TreeView row to Gtk TreeStore insert function?

I am trying to insert a row into a Gtk.TreeStore, for which I have to pass the selected row number from Gtk.TreeView. I found the solution for PyGTK but not for PyGObject.
For PyGTK the insert function looks like this (http://www.pygtk.org/pygtk2reference/class-gtktreestore.html#method-gtktreestore--insert):
def insert(parent, position, row=None)
The position can be queried like this:
treeview = Gtk.TreeView()
selection = treeview.get_selection()
model, iter = selection.get_selected()
path = iter.get_selected_rows()[0]
index = path.get_indices()[0]
But in PyGObject I get the error:
self.index = self.path.get_indices()[0]
AttributeError: 'LayerDataStore' object has no attribute 'get_indices'
How can I get the integer value of the row number? Am I approaching the problem in a weird way? It seems like the solution should be simpler and have less code.
Further Reading:
This is the description of the insert function in GTK3:
https://lazka.github.io/pgi-docs/Gtk-3.0/classes/TreeStore.html#Gtk.TreeStore.insert
Similar question for PyGTK:
Getting the row number of Gtk TreeView
Similar question for C++:
Get data from selected row of gtk treeview - gtkmm, c++
Finally figured it out. But I am not sure if there is a simpler solution:
First call select on the TreeView:
tree = Gtk.TreeView()
select = tree.get_selection()
select is then a Gtk.TreeSelection. We use this object to call get_selected_rows():
selected_rows = select.get_selected_rows()
The function returns a tuple of a LayerDataStore and a GtkTreePath when a row is selected. Otherwise the GtkTreePath is an empty list [].
Then assign the GtkTreePath to a variable:
path = selected_rows[1]
Path is now a list of the GtkTreePath or an empty list [] if nothing is selected. You can insert an if-function here to avoid getting any Errors.
We then have to unpack the list by using:
row = path[0]
Now the variable row is a TreePath and the print function will return 0 for the first row, 1 for the second row and so on. For nested trees it will return 0:0 for the first nested object in the first row, 0:1 for the second object in the first row and so on.
With the get_indices function we can convert the TreePath to a list:
index = row.get_indices()
The print function will now print [0] for the first row and [1] for the second. The nested objects are [0,0] for the first object of the first row and [0,1] for the second nested object of the first row.
Because I am just interested in the row number itself I am using this assignment to get only the row number:
row_number = index[0]
Finally the row number is passed to the TreeStore:
store.insert(None, row_number, [True, "New Layer")])
Helpful links:
https://lazka.github.io/pgi-docs/Gtk-3.0/classes/TreeSelection.html
https://lazka.github.io/pgi-docs/Gtk-3.0/structs/TreePath.html
https://lazka.github.io/pgi-docs/Gtk-3.0/classes/TreeView.html
https://lazka.github.io/pgi-docs/Gtk-3.0/classes/TreeStore.html

Scanning data from cell array and removing based on file extensions

I have a cell array that is a list of file names. I transposed them because I find that easier to work with. Now I am attempting to go through each line in each cell and remove the lines based on their file extension. Eventually, I want to use this list as file names to import data from. This is how I transpose the list
for i = 1:numel(F);
a = F(1,i);
b{i} = [a{:}'];
end;
The code I am using to try and read the data in each cell keeps giving me the error input must be of type double or string. Any ideas?
for i = 1:numel(b);
for k = 1:numel(b{1,i});
b(cellfun(textscan(b{1,i}(k,1),'%s.lbl',numel(b)),b))=[];
end;
end;
Thanks in advance.
EDIT: This is for MATLAB. Should have been clear on that. Thanks Brian.
EDIT2: whos for F is
Name Size Bytes Class Attributes
b 1x11 13986188 cell
while for a is
Name Size Bytes Class Attributes
a 1x1 118408 cell
From your description I am not certain how your F array looks, but assuming
F = {'file1.ext1', 'file2.ext2', 'file3.ext2', 'file2.ext1'};
you could remove all files ending with .ext2 like this:
F = F(cellfun('isempty', regexpi(F, '\.ext2$')));
regexpi, which operates on each element in the cell array, returns [] for all files not matching the expression. The cellfun call converts the cell array to a logical array with false at positions corresponding to files ending with .ext2and true for all others. The resulting array may be used as a logical index to F that returns the files that should be kept.
You're using cellfun wrong. It's signature is [A1,...,Am] = cellfun(func,C1,...,Cn). It takes a function as first argument, but you're passing it the result of textscan, which is a cell array of the matching strings. The second argument is a cell array as it should be, but it doesn't make sense to call it over and over in a loop. `cellfunĀ“'s job is to write the loop for you when you want to do the same thing to every cell in a cell array.
Instead of parsing the filename yourself with textscan, I suggest you use fileparts
Since you're already looping over the cell array in transpose-step, it might make sense to do the filtering there. It might look something like this:
for i = 1:numel(F);
a = F(1,i);
[~,~,ext] = fileparts(a{:});
if strcmpi(ext, '.lbl')
b{i} = [a{:}'];
end
end;

assigning values to a field of an structure array in MATLAB

I want to replace the value of the fields in a structure array. For example, I want to replace all 1's with 3's in the following construction.
a(1).b = 1;
a(2).b = 2;
a(3).b = 1;
a([a.b] == 1).b = 3; % This doesn't work and spits out:
% "Insufficient outputs from right hand side to satisfy comma separated
% list expansion on left hand side. Missing [] are the most likely cause."
Is there an easy syntax for this? I want to avoid ugly for loops for such simple operation.
Credits go to #Slayton, but you actually can do the same thing for assigning values too, using deal:
[a([a.b]==1).b]=deal(3)
So breakdown:
[a.b]
retrieves all b fields of the array a and puts this comma-separated-list in an array.
a([a.b]==1)
uses logical indexing to index only the elements of a that satisfy the constraint. Subsequently the full command above assigns the value 3 to all elements of the resulting comma-separated-list according to this.
You can retrieve that the value of a field for each struct in an array using cell notation.
bVals = {a.b};
bVals = cell2mat( bVals );
AFAIK, you can't do the same thing for inserting values into an array of structs. You'll have to use a loop.