2009-09-21 2 views
14

После игры с символическими и численными возможностями Mathematica я считаю, что это хороший язык программирования. Однако то, что делает его менее привлекательным как язык общего назначения, - это отсутствие типа данных типа C (типа записи, как известно в Паскале). Как я могу обойти эту проблему?Тип данных структуры в Mathematica?

ответ

8

Если я правильно понимаю ваш вопрос, вы можете просто написать что-то вроде этого:

 
x[foo] = bar 
x[bar] = baz 
x[1] = 7 
x[7] = 1 
?x 

Тогда для доступа к данным для любого конкретного индекса просто введите тот же (например, x[1] вернется 7, x[foo] вернется bar).

+0

Этот способ ведения дел имеет одно реальное преимущество над подходным принципом, предложенным сакрай: он позволяет вам мутировать «поля» «структуры» простым способом. – Pillsy

+2

Проблема с ответом: если «поле» - это список, его элементы не могут быть изменены индивидуально. Например, x [foo] = {1,2}; x [foo] [[1]] = 3 (* попытка изменить элемент списка *) приведет к ошибке, так как x [foo] не является Lvalue. Таким образом, он все еще не полностью заменяет функциональность C struct. – felix

+1

Вам нужно полностью заменить старое значение, а не просто изменить одно значение списка: f ["foo"] = {1, 2}; f ["foo"] = (ReplacePart [f ["foo"], 1 -> 3]) Кроме того, я бы использовал строки или целые числа для ключей, а не символов. Есть также несколько сложных задач, которые вы можете сделать, установив UpValues ​​для Set. –

14

Update: Mathematica 10 представила Association, который имеет многие из наиболее важных свойств struct. (См. new answer.) Оригинальная, несколько устаревшая версия этого ответа приведена ниже.


Вы можете использовать Mathematica правила списки, чтобы имитировать тип данных структуры C-подобный. Например,:.

person = {firstName -> "John", lastName -> "Doe"} 

Вы можете получить доступ к полей записи с помощью оператора /.:

firstName /. person 

дает John.

lastName /. person 

Doe.

Чтобы обновить поле записи, снабдите обновленное поле в списке:

PrependTo[person , firstName -> "Jane"] 

firstName /. person затем дает Jane.

Также см. Mathematica документация на transformation rules.

+2

Выполнение нескольких изменений с использованием предваряющего означает, что в списке лиц появится ряд неиспользуемых правил. Не очень эффективно. –

+0

Обратите внимание, что Mathematica 10 представила ['Association'] (http://reference.wolfram.com/language/ref/Association.html), который имеет многие из самых важных свойств' struct'. См. [Новый ответ] (http://stackoverflow.com/a/33465106/330202). –

2

Этот способ может работать:

x[foo] = bar 

x[bar] = baz 

x[1] = 7 

x[7] = 1 

x[c] = {{1,2,3},{4,5,6}} 

, а также для изменения элементов поля списка вы можете так следующее:

x[c] = ReplacePart[x[c], {1, 1} -> 8] 

, которая возвращает:

x[c] = {{8,2,3},{4,5,6}} 
3

Mathematica 10 ввел Association, который имеет многие из наиболее важных свойств struct.

someData = <| "name" -> "Bob", "age" -> 23 |> 

In[1]:= someData["name"] 
Out[1]= Bob 

In[2]:= someData["age"] 
Out[2]= 23 

In[3]:= someData[[2]] 
Out[3]= 23 

Для получения дополнительной информации см

Смежные вопросы