Это формат номера в индийском стиле, где 100 000 (записано как 10000) - это один «lakh» .
Перевод и упрощение кода Objective-C из Формат валюты для разных локалей в iOS дает:
let formatter = NSNumberFormatter()
formatter.numberStyle = .DecimalStyle
formatter.locale = NSLocale(localeIdentifier: "en_IN") // English (India) locale
let number = 12345678
let string = formatter.stringFromNumber(number)!
println(string) // 1,23,45,678
Обновление для Swift 3:
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.locale = Locale(identifier: "en_IN") // English (India) locale
let number = 12345678
let string = formatter.string(for: number)!
print(string) // 1,23,45,678
Чтобы получить каждую комбинацию возможных чисел для каждого поля, используйте ndgrid
.
[Numbers{1:3}] = ndgrid(a,b,c);
Наличие пронумерованных структур, находящихся в рабочем пространстве, как вы описываете, затрудняет программный доступ к ним, и вы должны избегать его, если это возможно; однако к ним все еще можно получить доступ, используя eval
.
evalPattern = strjoin(strcat(Names,'%d'), '.'); % 'a%d.b%d.c%d'
firstNumbers = cellfun(@(n) n(1), Numbers); % [1 4 2]
firstElement = eval(sprintf(evalPattern,firstNumbers)); % returns the value of a1.b4.c2
result = nan([size(firstElement) size(Numbers{1}]);
for ii = 1:numel(Numbers{1})
iiNumbers = cellfun(@(n) n(ii), Numbers);
result(:,:,ii) = eval(sprintf(evalPattern,iiNumbers));
end
Хорошо, это заняло больше времени, чем я ожидал, но следующий код должен работать для произвольного числа имен и чисел, учитывая следующие требования:
regexp
или что-то вроде этого. ax.bx.cx....
могут быть сохранены в какой-то подчиненной структуре вашим приложением (заранее). ax.bx.cx...
, а размеры матрицы равны. Итак, сценарий довольно длинный и - я боюсь - нуждается в некотором объяснении. Пожалуйста, просто спросите. Основная идея состоит в том, чтобы проходить через структуру (ы), пока конкретные «потомки» все еще являются структурами. Это обеспечивает произвольную «глубину» структур, то есть количество имен и номеров.
Я расширил ваши данные, так что вы видите, что они также работают для (а) дополнительных имен, (б) дополнительных чисел и (в) разных размеров матрицы. Конечно, это также работает с вашими исходными данными.
Кроме того, вначале не нужно Names
или Numbers
, поскольку эта информация автоматически извлекается из (должна быть там подчиненной) структуры.
(Внимание: написано в Octave. Я пытался проверить, что все функции также доступны в Matlab. Пожалуйста, сообщите о любых проблемах, если это не так. Затем я проведу рефакторинг кода.)
% Structs given.
a1.b4.c2.d3 = ones(4, 4);
a1.b4.c4.d3 = ones(4, 4) * 2;
a1.b4.c5.d3 = ones(4, 4) * 3;
a1.b6.c2.d3 = ones(4, 4) * 4;
a1.b6.c4.d3 = ones(4, 4) * 5;
a1.b6.c5.d3 = ones(4, 4) * 6;
a2.b4.c2.d3 = ones(4, 4) * 7;
a2.b4.c4.d3 = ones(4, 4) * 8;
a2.b4.c5.d3 = ones(4, 4) * 9;
a2.b6.c2.d3 = ones(4, 4) * 10;
a2.b6.c4.d3 = ones(4, 4) * 11;
a2.b6.c5.d3 = ones(4, 4) * 12;
% REQUIREMENT: Store your structs in some superordinated struct.
super.a1 = a1;
super.a2 = a2;
% Initialize combined struct for names and numbers.
NamesNumbers = struct();
% Initialize Names cell array.
Names = {};
% Extract names and numbers from superordinated struct.
totalNames = 0;
totalNumbers = 1;
current = super;
while (isstruct(current))
fields = fieldnames(current);
totalNames = totalNames + 1;
totalNumbers = totalNumbers * numel(fields);
for iField = 1:numel(fields)
field = fields{iField};
name = field(1);
Names{totalNames} = name;
number = field(2:end);
if (isfield(NamesNumbers, name) == false)
NamesNumbers.(name) = str2num(number);
else
NamesNumbers.(name) = [NamesNumbers.(name) str2num(number)];
end
end
current = current.(fields{1});
if (isstruct(current) == false)
[nRows, nCols] = size(current);
end
end
% Extract all values from superordinated struct.
level = struct2cell(super);
while (isstruct([level{:}]))
level = struct2cell([level{:}]);
end
values = vertcat(level{:});
% Determine indices.
maxIdx = cellfun(@(x) max(x), struct2cell(NamesNumbers));
idx = zeros([totalNumbers, totalNames]);
factorProd = 1;
for iName = 1:totalNames
numbers = NamesNumbers.(Names{iName});
n = numel(numbers);
factorProd = factorProd * n;
inner = totalNumbers / factorProd;
resh = totalNumbers * n / factorProd;
outer = factorProd / n;
column = repmat(reshape(repmat(numbers, inner, 1), resh, 1), outer, 1);
START = (iName - 1) * totalNumbers + 1;
STOP = iName * totalNumbers;
idx(START:STOP) = column;
end
% Initialize output.
output = zeros([nRows nCols maxIdx']);
% Fill output with values.
for iIdx = 1:size(idx, 1)
temp = num2cell(idx(iIdx, :));
START = (iIdx - 1) * nRows + 1;
STOP = iIdx * nRows;
output(:, :, temp{:}) = values(START:STOP, :);
end