|
575 | 575 | end |
576 | 576 | opcell{1} = obj.data; |
577 | 577 |
|
| 578 | + % forward value extraction loop |
578 | 579 | for i = 1:oplen |
579 | 580 | idx = idxkey(i); |
580 | 581 | if (strcmp(idx.type, '.')) |
|
597 | 598 | continue |
598 | 599 | end |
599 | 600 | if (ischar(idx.subs) && strcmp(idx.subs, 'v') && i < oplen && strcmp(idxkey(i + 1).type, '()')) |
| 601 | + % expand struct or cell when using .v(index) more |
| 602 | + % than the length |
| 603 | + nextsubs = idxkey(i + 1).subs; |
| 604 | + if iscell(nextsubs) |
| 605 | + nextsubs = nextsubs{1}; |
| 606 | + end |
| 607 | + if isnumeric(nextsubs) && isscalar(nextsubs) |
| 608 | + if isstruct(opcell{i}) && nextsubs > numel(opcell{i}) |
| 609 | + fnames = fieldnames(opcell{i}); |
| 610 | + if (~isempty(fnames)) |
| 611 | + for fi = 1:length(fnames) |
| 612 | + opcell{i}(nextsubs).(fnames{fi}) = []; |
| 613 | + end |
| 614 | + end |
| 615 | + elseif iscell(opcell{i}) && nextsubs > numel(opcell{i}) |
| 616 | + opcell{i}{nextsubs} = []; |
| 617 | + end |
| 618 | + end |
600 | 619 | opcell{i + 1} = opcell{i}; |
601 | | - if (i < oplen && iscell(opcell{i})) |
| 620 | + if iscell(opcell{i}) |
602 | 621 | idxkey(i + 1).type = '{}'; |
603 | 622 | end |
604 | 623 | continue |
|
635 | 654 | end |
636 | 655 | end |
637 | 656 |
|
638 | | - if (obj.flags__.isoctave_) && (ismap_(obj.flags__, opcell{i})) |
639 | | - opcell{i}(idx.subs) = otherobj; |
640 | | - opcell{end - 1} = opcell{i}; |
| 657 | + if (oplen >= 2 && ischar(idxkey(oplen - 1).subs) && strcmp(idxkey(oplen - 1).subs, 'v') && strcmp(idxkey(oplen).type, '()')) |
| 658 | + % Handle .v(index) = value at any depth |
| 659 | + nextsubs = idxkey(oplen).subs; |
| 660 | + if iscell(nextsubs) |
| 661 | + nextsubs = nextsubs{1}; |
| 662 | + end |
| 663 | + if iscell(opcell{oplen}) |
| 664 | + opcell{oplen}{nextsubs} = otherobj; |
| 665 | + elseif isstruct(opcell{oplen}) && isempty(fieldnames(opcell{oplen})) |
| 666 | + % Empty struct with no fields - just replace |
| 667 | + opcell{oplen} = otherobj; |
| 668 | + else |
| 669 | + opcell{oplen}(nextsubs) = otherobj; |
| 670 | + end |
| 671 | + opcell{oplen + 1} = opcell{oplen}; |
| 672 | + elseif (obj.flags__.isoctave_) && (ismap_(obj.flags__, opcell{oplen})) |
| 673 | + opcell{oplen}(idx.subs) = otherobj; |
| 674 | + opcell{oplen + 1} = opcell{oplen}; |
641 | 675 | else |
642 | 676 | if (ischar(idx.subs) && ~isempty(idx.subs) && idx.subs(1) == char(36)) |
643 | | - opcell{end - 1} = obj.call_('jsonpath', opcell{i}, idx.subs, otherobj); |
| 677 | + opcell{oplen + 1} = obj.call_('jsonpath', opcell{oplen}, idx.subs, otherobj); |
644 | 678 | else |
645 | | - if (ismap_(obj.flags__, opcell{i})) |
| 679 | + if (ismap_(obj.flags__, opcell{oplen})) |
646 | 680 | idx = struct('type', '()', 'subs', idx.subs); |
647 | 681 | end |
648 | 682 | try |
649 | | - opcell{end - 1} = subsasgn(opcell{i}, idx, otherobj); |
| 683 | + opcell{oplen + 1} = subsasgn(opcell{oplen}, idx, otherobj); |
650 | 684 | catch |
651 | | - opcell{i}.(idx.subs) = otherobj; |
652 | | - opcell{end - 1} = opcell{i}; |
| 685 | + opcell{oplen}.(idx.subs) = otherobj; |
| 686 | + opcell{oplen + 1} = opcell{oplen}; |
653 | 687 | end |
654 | 688 | end |
655 | 689 | end |
656 | 690 |
|
| 691 | + % Propagate result for backward loop |
| 692 | + opcell{oplen} = opcell{oplen + 1}; |
| 693 | + |
| 694 | + % backward assignment along the reversed path |
657 | 695 | for i = oplen - 1:-1:1 |
658 | 696 | idx = idxkey(i); |
659 | 697 | if (ischar(idx.subs) && strcmp(idx.type, '.') && ismap_(obj.flags__, opcell{i})) |
|
677 | 715 | end |
678 | 716 |
|
679 | 717 | if (i > 1 && ischar(idxkey(i - 1).subs) && strcmp(idxkey(i - 1).subs, 'v')) |
680 | | - if (iscell(opcell{i}) && ~isempty(idx.subs)) |
| 718 | + if (~isempty(idx.subs) && (iscell(opcell{i}) || (isstruct(opcell{i}) && ~isempty(fieldnames(opcell{i}))))) |
| 719 | + % Add missing fields to opcell{i} if opcell{i+1} has more fields |
| 720 | + if isstruct(opcell{i}) && isstruct(opcell{i + 1}) |
| 721 | + newfields = fieldnames(opcell{i + 1}); |
| 722 | + for fi = 1:length(newfields) |
| 723 | + if ~isfield(opcell{i}, newfields{fi}) |
| 724 | + [opcell{i}.(newfields{fi})] = deal([]); |
| 725 | + end |
| 726 | + end |
| 727 | + end |
681 | 728 | opcell{i} = subsasgn(opcell{i}, idx, opcell{i + 1}); |
682 | 729 | else |
683 | 730 | opcell{i} = opcell{i + 1}; |
|
0 commit comments