Find position of cell array within another cell array or table or in a structure

조회 수: 79 (최근 30일)
I have a number of nodes on a graph and a number of edges that connect them. Attached to each edge is a structure wear the first field is the EndNodes data from the edge table which defines the edges. I want to search the struct array to find the structure that matches the selected edge EndNodes but I can't figure out the syntax. The closest I've come is something like this where EdgeData is the struct array and data is the 2x1 cell containing the desired EndNodes:
selectedEdge=EdgeData(ismember(data,array2table({app.EdgeData.EndNodes}).Var1))
This fails because the inputs of ismember must be character arrays rather than cell arrays containing character arrays. Concatenating them could work but I would then simply be detecting if the two names of the edges are present and not whether they are contained together within one field. I've tried ==, ismember, strcmp, isequal and I've run out of things to try and ideas of documentation to comb through. It's possible that arrayfun might be the way forward but I don't really understand it honestly
PS yes I'm using app designer hence the referencing of EdgeData as a property
  댓글 수: 2
Fangjun Jiang
Fangjun Jiang 2025년 12월 17일 15:53
Providing an example of the data would be most helpful to understand the need. You can construct a simplifed data using code.
Timothy
Timothy 2025년 12월 17일 16:35
Of course. As mentioned the data is all EndNode data which, in case you're not familiar with the required format of edges on graphs, are 1x2 cells (sorry not 2x1) where each cell in the array is the identifier which references a specific node - in this case each cell array contains two character arrays which is the name of a train junction.
For example each cell would look something like this:
data={{'Littleport'}{'West River'}}

댓글을 달려면 로그인하십시오.

채택된 답변

Fangjun Jiang
Fangjun Jiang 2025년 12월 17일 17:05
Something like this?
data={{'Littleport'},{'West River'}};
EndNodes={{'Bigport'},{'West River'};
{'Littleport'},{'West River'};
{'Littleport'},{'East River'}};
Index=ismember(string(EndNodes),string(data),'row')
Index = 3×1 logical array
0 1 0
  댓글 수: 5
Timothy
Timothy 2025년 12월 19일 17:04
This is perfect. Been knocking my head against the table for 3 days on this. I knew it would be something to do with cellfun but I still don't know how to use it. Only note for anyone who looks at this in the future is that for a list derived from a struct array, curly braces {} are needed to create a cell otherwise the transpose function sees each value separately and considers it "too many arguments"
Fangjun Jiang
Fangjun Jiang 2025년 12월 19일 19:11
The lesson learned here is to provide an "EXACT" example inputs and the expected outputs for the most efficient Q&A. Imaging if you had provided the correct "data" and "EndNodes" initially, there would be no need for this lengthy discussion. You don't even need to mention your specific field like "graph" or "edge".
You can use the "Insert a line of code" button and then "RUN" it to provide a valid example data. Note that the example you previously provided in your comment text is not valid.
data={{'Littleport'}{'West River'}}
Invalid expression. When calling a function or indexing a variable, use parentheses. Otherwise, check for mismatched delimiters.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Steven Lord
Steven Lord 2025년 12월 18일 15:53
Are you using a graph or digraph object? Do you have the additional struct information stored as a separate variable or have you added that information as custom attributes in the Edges and/or Nodes properties of the graph/digraph object? I recommend the latter if you're using the object.
If you have that information as custom attributes of a graph or digraph object, to locate the data for a specific edge given the end nodes use the findedge function. Then use that edge index to index into the Edges property.
s = [1 1 2 2 3];
t = [2 4 3 4 4];
G = digraph(s,t);
G.Edges.Weight = [10 20 30 40 50]';
disp(G.Edges)
EndNodes Weight ________ ______ 1 2 10 1 4 20 2 3 30 2 4 40 3 4 50
whichEdge = findedge(G, 2, 3)
whichEdge = 3
theWeight = G.Edges{whichEdge, 'Weight'}
theWeight = 30
Note that if you've constructed the digraph using a possibly unordered set of source and target indices, and the additional edge information is stored in a separate variable, the order may be different. The EndNodes list order is not guaranteed to be the same as the order in which the edges were specified when the graph/digraph object was created.
s2 = [1 1 3 2 2];
t2 = [2 4 4 3 4];
w2 = [10 20 50 30 40];
D = digraph(s2, t2, w2);
D.Edges
ans = 5×2 table
EndNodes Weight ________ ______ 1 2 10 1 4 20 2 3 30 2 4 40 3 4 50
The third edge in the Edges property is not the one specified by the third elements in s2, t2, and w2. So if you were to findedge and use that to index into w2, you'd get the wrong answer. That's one reason I recommend storing both the edge information and the additional attributes inside the graph/digraph object.
E = findedge(D, 2, 3) % Correct edge located
E = 3
weight = w2(E) % but w2 is in a different order than Weight so wrongly returns 50
weight = 50
weight = D.Edges{E, "Weight"} % Correctly returns weight of 30
weight = 30
  댓글 수: 5
Steven Lord
Steven Lord 2025년 12월 19일 13:20
What's in the cell? Is it text data? If so there are lots of functions for searching for data in cell arrays containing text.
C = {'apple', 'banana', 'cherry', 'durian'}
C = 1×4 cell array
{'apple'} {'banana'} {'cherry'} {'durian'}
namesContainingTheLetterA = contains(C, 'a')
namesContainingTheLetterA = 1×4 logical array
1 1 0 1
C(namesContainingTheLetterA)
ans = 1×3 cell array
{'apple'} {'banana'} {'durian'}
namesWith6Letters = strlength(C) == 6
namesWith6Letters = 1×4 logical array
0 1 1 1
C(namesWith6Letters)
ans = 1×3 cell array
{'banana'} {'cherry'} {'durian'}
startsWithB = startsWith(C, 'b')
startsWithB = 1×4 logical array
0 1 0 0
C(startsWithB)
ans = 1×1 cell array
{'banana'}
The set functions like ismember may also be of use.
Timothy
Timothy 2025년 12월 19일 13:32
Each cell is a cell array of two strings as I said. Using the fruit example it could be {{'apple', 'banana'} {'cherry', 'durian'}}. This why ismember and contains havent been working for me

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Matrices and Arrays에 대해 자세히 알아보기

제품


릴리스

R2024b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by