Message Boards Message Boards

0
|
4097 Views
|
2 Replies
|
2 Total Likes
View groups...
Share
Share this post:

ArrayRules for non-symmetric, very irregular list

Posted 11 years ago
Let there be a sample list as ,
l = {a, {{b, c}}, {d, e}, {f}, {{g, {y}, u, h}, {{{{k, j}}}}},k, {{{{q}, {w}, {r}, {x}}}}};
ArrayRules[l]
ArrayRules::rect: Nonrectangular array encountered. >>
is the error thrown. So, I was just wondering that if someone needs to preserve list structure using a similar kind of functionality, than what might be steps needed. My intention is to pass data to replace later rather than as rule in ArrayRules.
I could parse list to find positions information like ArrayRules using following code,
 ListRules[l_List] :=
 Module[{l1 = l, l11, s1, pos, M, tpos, trpos, sp, ntrpos, temntrpos,
    fin, fin2},
   {l11 = {#} & /@ l1,
    s1 = Map[{#, Position[l11, #]} &, l11,Infinity] /. {a_, {{s___}}} -> {s} //. {d___, {}, e___} -> {d,e},
    pos = Table[s1[[i]] //. {___, {a___List}, ___} -> a, {i, 1,Length[s1]}],
    M = Last[SortBy[pos, Length]] // Length,
    tpos = Table[If[Length[pos[[i]]] < M, PadRight[pos[[i]], M, 1], pos[[i]]], {i, 1, Length[pos]}],
    }; tpos]
listrules= ListRules[l]
gives
 {{1, 1, 1, 1, 1, 1, 1}, {2, 1, 1, 1, 1, 1, 1}, {2, 1, 1, 2, 1, 1, 1},
  {3, 1, 1, 1, 1, 1, 1}, {3, 1, 2, 1, 1, 1, 1}, {4, 1, 1, 1, 1, 1, 1},
  {5, 1, 1, 1, 1, 1, 1}, {5, 1, 1, 2, 1, 1, 1}, {5, 1, 1, 3, 1, 1, 1},
  {5, 1, 1, 4, 1, 1, 1}, {5, 1, 2, 1, 1, 1, 1}, {6, 1, 1, 1, 1, 1, 1},
  {5, 1, 2, 1, 1, 1, 2}, {5, 1, 2, 1, 1, 1, 1}, {6, 1, 1, 1, 1, 1, 1},
  {7, 1, 1, 1, 1, 1, 1}, {7, 1, 1, 1, 2, 1, 1}, {7, 1, 1, 1, 3, 1, 1}, {7, 1, 1, 1, 4, 1, 1}}

Than I tried to create it back to a list using following method,
 CreateList[s_List] :=
 Module[{tpos = s, trpos, sp, ntrpos, temntrpos, fin, fin2, t, x, y,
    h}, {trpos =
     Table[tpos[[i]] -> RandomInteger[100], {i, 1, Length[tpos]}],
    sp = SparseArray[trpos],
    ntrpos = Normal[sp],
    temntrpos = ntrpos //. {a___, {h___, 0 ..}, b___} -> {a, h, b} //. {a___, {}, b___} -> {a, b}
    }; temntrpos
   ]
CreateList[listrules]
gives,
{{{{{{76}}}}}, {{{{{82}}, {{83}}}}}, {{{{{67}}}, {{{19}}}}}, {{{{{32}}}}}, {{{{{51}}, {{22}}, {{60}}, {{1}}}, {{{{26,59}}}}}}, {{{{{12}}}}}, {{{{{6}, {78}, {34}, {72}}}}}}

It shows that it has been able to retain nesting structure but there are extra braces associated, here I am getting defeated repeatedly. I tried to use Dimension, Depth etc. I can get rid of nesting for  single elements by associating dimension from original list with them and flattening all those with maximum dimension as 1. But in case of multiple nesting, I am failing.

Can someone show me way ?

Thanks
POSTED BY: Pankaj Sejwal
2 Replies
Posted 11 years ago
Thanks for replying but i was looking forward to  sticking to my approach to find a solution. I want to save list as a template for both spare and non-sparse arrays. I need to know that what information I shall associate with each nested list in hierarchy that will help me decide the right number of braces.
POSTED BY: Pankaj Sejwal
ArrayRules assumes the argument is already nicely packaged.

Here is one way to extract the rules for this object.
Position[l, _Symbol] by itself would pull out the variables and the function name List;
adding the PatternTest "?notList"  tells Position to ignore Lists.
 In[1]:= l = {a, {{b, c}}, {d, e}, {f}, {{g, {y}, u, h}, {{{{k, j}}}}},
    k, {{{{q}, {w}, {r}, {x}}}}};
 
 In[2]:= notList[z_] := z =!= List
 
 In[3]:= pos = Position[l, _Symbol?notList]
 Out[3]= {{1}, {2, 1, 1}, {2, 1, 2}, {3, 1}, {3, 2}, {4, 1}, {5, 1, 1}, {5, 1, 2,
   1}, {5, 1, 3}, {5, 1, 4}, {5, 2, 1, 1, 1, 1}, {5, 2, 1, 1, 1, 2}, {6}, {7,
   1, 1, 1, 1}, {7, 1, 1, 2, 1}, {7, 1, 1, 3, 1}, {7, 1, 1, 4, 1}}

In[4]:= vals = Extract[l, pos]
Out[4]= {a, b, c, d, e, f, g, y, u, h, k, j, k, q, w, r, x}

In[5]:= Thread[Rule[pos, vals]]

Out[5]= {{1} -> a, {2, 1, 1} -> b, {2, 1, 2} -> c, {3, 1} -> d, {3, 2} -> e,
  {4, 1} -> f, {5, 1, 1} -> g, {5, 1, 2, 1} -> y, {5, 1, 3} -> u,
  {5, 1, 4} -> h, {5, 2, 1, 1, 1, 1} -> k, {5, 2, 1, 1, 1, 2} -> j,
  {6} -> k, {7, 1, 1, 1, 1} -> q, {7, 1, 1, 2, 1} -> w,
  {7, 1, 1, 3, 1} -> r, {7, 1, 1, 4, 1} -> x}

In[6]:= $Version
Out[6]= "9.0 for Microsoft Windows (64-bit) (January 25, 2013)"
POSTED BY: Bruce Miller
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract