多次元配列からリスト(UL・OL要素)を生成する

オブジェクトの入れ子にも対応したバージョン
function array2list(array, ordered, doc) {
  if (!doc) doc = document;
  var list = doc.createElement(ordered ? 'ol' : 'ul'), li;
  for (var i = 0; i < array.length; ++i) {
    var item = array[i];
    var itemType = Object.prototype.toString.call(item);
    if (itemType === '[object Array]') {
      if (!li) li = list.appendChild(doc.createElement('li'));
      li.appendChild(arguments.callee(item, ordered, doc));
    } else {
      li = list.appendChild(doc.createElement('li'));
      if (itemType === '[object Number]') item = String(item);
      if (itemType === '[object String]') item = doc.createTextNode(item);
      li.appendChild(item);
    }
  }
  return list;
}

第2引数のorderedでol要素にする(true)かul要素にする(false)かを決める。

例: JavaScript 第5版の1章の目次

var toc = [
  '1章 JavaScriptの概要',
  [
    '1.1 JavaScriptとは何か',
    [
      '1.1.1 JavaScriptとJavaは同じものか',
      '1.1.2 JavaScriptは簡単か'
    ],
    '1.2 JavaScriptのさまざまなバージョン',
    '1.3 クライアントサイドJavaScript',
    [
      '1.3.1 クライアントサイドJavaScriptの例',
    ],
    '1.4 クライアントサイドJavaScript以外のJavaScript',
    '1.5 JavaScriptの学習方法'
  ]
];

array2list(toc);  // => 戻り値はリスト(UL要素)

以下のようなリストが生成される。

<ul>
  <li>1章 JavaScriptの概要
  <ul>
    <li>1.1 JavaScriptとは何か
    <ul>
      <li>1.1.1 JavaScriptとJavaは同じものか</li>
      <li>1.1.2 JavaScriptは簡単か</li>
    </ul>
    </li>
    <li>1.2 JavaScriptのさまざまなバージョン</li>
    <li>1.3 クライアントサイドJavaScript
    <ul>
      <li>1.3.1 クライアントサイドJavaScriptの例</li>
    </ul>
    </li>
    <li>1.4 クライアントサイドJavaScript以外のJavaScript</li>
    <li>1.5 JavaScriptの学習方法</li>
  </ul>
  </li>
</ul>

余談

これを使えば、以前やった見出しを抽出してリスト化する問題(HTML文書内の見出しを抽出し、OL要素で階層化する - rikubaの日記)も簡単にできるのではないかと思ったけど、ややこしい部分が多次元配列を作る作業に移動しただけで、あまり変わらないというか、余計大変っぽい...。