Skip to content

Commit 04300e9

Browse files
committed
[xarray] allow using dim tag to access slices
1 parent d40b6ed commit 04300e9

File tree

1 file changed

+109
-2
lines changed

1 file changed

+109
-2
lines changed

jdict.m

Lines changed: 109 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,58 @@
205205
if (isa(val, 'jdict'))
206206
val = val.data;
207207
end
208+
209+
% check if dimension-based indexing
210+
dims = obj.getattr(trackpath, 'dims');
211+
if (~isempty(dims) && iscell(dims) && i < oplen && strcmp(idxkey(i + 1).type, '()'))
212+
dimpos = find(strcmp(dims, onekey));
213+
if (~isempty(dimpos) && ~isempty(idxkey(i + 1).subs))
214+
nddata = length(dims);
215+
indices = cell(1, nddata);
216+
for j = 1:nddata
217+
indices{j} = ':';
218+
end
219+
indices{dimpos(1)} = idxkey(i + 1).subs{1};
220+
subsargs = struct('type', '()', 'subs', {indices});
221+
val = subsref(val, subsargs);
222+
newobj = jdict(val);
223+
newobj.attr = obj.attr;
224+
newobj.currentpath = trackpath;
225+
val = newobj;
226+
i = i + 2;
227+
continue
228+
end
229+
end
230+
208231
if (ischar(onekey) && ~isempty(onekey) && onekey(1) == char(36))
209232
val = obj.call_('jsonpath', val, onekey);
210233
trackpath = onekey;
211234
elseif (isstruct(val))
212-
val = val.(onekey);
213-
trackpath = [trackpath '.' onekey];
235+
% check if struct array - if so, get field from all elements
236+
if (numel(val) > 1 && isfield(val, onekey))
237+
% struct array - extract field from all elements
238+
val = {val.(onekey)};
239+
if (all(cellfun(@isnumeric, val)) && all(cellfun(@(x) isequal(size(x), size(val{1})), val)))
240+
% try to concatenate if all same size numeric
241+
try
242+
val = cat(ndims(val{1}) + 1, val{:});
243+
catch
244+
% keep as cell if concatenation fails
245+
end
246+
end
247+
trackpath = [trackpath '.' onekey];
248+
% check if next operation is () for indexing the result
249+
if (i < oplen && strcmp(idxkey(i + 1).type, '()') && ~isempty(idxkey(i + 1).subs))
250+
subsargs = struct('type', '()', 'subs', idxkey(i + 1).subs);
251+
val = subsref(val, subsargs);
252+
i = i + 2;
253+
continue
254+
end
255+
else
256+
% single struct or scalar field access
257+
val = val.(onekey);
258+
trackpath = [trackpath '.' onekey];
259+
end
214260
elseif (isa(val, 'containers.Map') || isa(val, 'dictionary'))
215261
val = val(onekey);
216262
trackpath = [trackpath '.' onekey];
@@ -280,6 +326,67 @@
280326
end
281327
end
282328

329+
% handle dimension-based assignment like jd.time(1:10) = newval
330+
if (oplen >= 2 && strcmp(idxkey(oplen).type, '()'))
331+
% check if second-to-last is a dimension name
332+
if (strcmp(idxkey(oplen - 1).type, '.') && ischar(idxkey(oplen - 1).subs))
333+
dimname = idxkey(oplen - 1).subs;
334+
% build path to the data
335+
temppath = obj.currentpath;
336+
for i = 1:oplen - 2
337+
idx = idxkey(i);
338+
if (strcmp(idx.type, '.') || strcmp(idx.type, '()'))
339+
if (iscell(idx.subs))
340+
onekey = idx.subs{1};
341+
else
342+
onekey = idx.subs;
343+
end
344+
if (ischar(onekey) && ~isempty(onekey))
345+
if (onekey(1) ~= char(36))
346+
temppath = [temppath '.' onekey];
347+
else
348+
temppath = onekey;
349+
end
350+
end
351+
end
352+
end
353+
% check if dimname is in dims
354+
dims = obj.getattr(temppath, 'dims');
355+
if (~isempty(dims) && iscell(dims))
356+
dimpos = find(strcmp(dims, dimname));
357+
if (~isempty(dimpos) && ~isempty(idxkey(oplen).subs))
358+
% navigate to the data
359+
data = obj.data;
360+
if (oplen > 2)
361+
data = subsref(obj, idxkey(1:oplen - 2));
362+
if (isa(data, 'jdict'))
363+
data = data.data;
364+
end
365+
end
366+
% build full indices
367+
nddata = length(dims);
368+
indices = cell(1, nddata);
369+
for j = 1:nddata
370+
indices{j} = ':';
371+
end
372+
indices{dimpos(1)} = idxkey(oplen).subs{1};
373+
% perform assignment
374+
subsargs = struct('type', '()', 'subs', {indices});
375+
if (oplen > 2)
376+
% need to assign back through the chain
377+
subidx = idxkey(1:oplen - 2);
378+
tempdata = subsref(obj.data, subidx);
379+
tempdata = subsasgn(tempdata, subsargs, otherobj);
380+
obj.data = subsasgn(obj.data, subidx, tempdata);
381+
else
382+
obj.data = subsasgn(obj.data, subsargs, otherobj);
383+
end
384+
return
385+
end
386+
end
387+
end
388+
end
389+
283390
oplen = length(idxkey);
284391
opcell = cell (1, oplen + 1);
285392
if (isempty(obj.data))

0 commit comments

Comments
 (0)