2009-09-21 13 views
14

Dopo aver giocato con le capacità simbolici e numerici di Mathematica, trovo che sia un linguaggio di programmazione decente, troppo. Tuttavia, qualcosa che lo rende meno attraente come linguaggio generico è la mancanza del tipo di dati struct C-like (o il tipo di record come noto in Pascal). Come posso aggirare questo problema?Analizza il tipo di dati in Mathematica?

risposta

8

Se ho capito bene la tua domanda, si può semplicemente scrivere cose come questa:

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

Poi per accedere ai dati per qualsiasi indice specifico basta digitare lo stesso (ad esempio, x[1] tornerà 7, x[foo] tornerà bar).

+0

Questo modo di fare le cose ha un vantaggio reale rispetto all'approccio regola suggerito da sakra: consente di mutare i "campi" della "struttura" in modo semplice. – Pillsy

+2

C'è un problema con la tua risposta: se un "campo" è una lista, i suoi elementi non possono essere modificati individualmente. Ad esempio, x [foo] = {1,2}; x [foo] [[1]] = 3 (* tentativo di modificare l'elemento di lista *) causerà un errore, perché x [foo] non è un Lvalue. Quindi non sostituisce completamente la funzionalità C struct. – felix

+1

È necessario sostituire completamente il vecchio valore, non solo modificare un singolo valore della lista: f ["foo"] = {1, 2}; f ["foo"] = (ReplacePart [f ["foo"], 1 -> 3]) Inoltre, userei stringhe o interi per le chiavi, non per i simboli. Ci sono anche alcuni affari difficili che puoi fare impostando UpValues ​​per Set. –

14

Aggiornamento: Mathematica 10 ha introdotto Association, che ha molte delle proprietà più importanti di un struct. (Vedi new answer.) La versione originale, in qualche modo deprecata, di questa risposta è sotto.


È possibile utilizzare una regolaMathematica elenca per simulare un tipo di dati struct C-like. Per esempio,:.

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

È possibile quindi accedere ai campi del record utilizzando l'operatore /.:

firstName /. person 

cede John.

lastName /. person 

cede Doe.

per aggiornare un campo di un record, anteporre il campo aggiornato alla lista:

PrependTo[person , firstName -> "Jane"] 

firstName /. person cede poi Jane.

Vedere anche la documentazione Mathematica su transformation rules.

+2

Apportare alcune modifiche usando la preposizione significa che un numero di regole inutilizzate apparirà nell'elenco delle persone. Non molto efficiente. –

+0

Si noti che Mathematica 10 ha introdotto ['Association'] (http://reference.wolfram.com/language/ref/Association.html), che ha molte delle proprietà più importanti di una' struct'. Vedi [nuova risposta] (http://stackoverflow.com/a/33465106/330202). –

2

In questo modo può funzionare:

x[foo] = bar 

x[bar] = baz 

x[1] = 7 

x[7] = 1 

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

e anche per cambiare gli elementi di un campo della lista è possibile quindi il seguente:

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

che restituisce:

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

Mathematica 10 ha introdotto Association, che ha molte delle proprietà più importanti di un 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 

Per ulteriori informazioni, vedere