61047


変数aはもともと配列という前提で、この配列をオブジェクトにまとめたいのですが、うまい方法が思いつきません。Object.assignだと代入になってしまいます。ご教示いただければ幸いです。

[code]

    let a = 'Japan, Tokyo, Chiyoda, Kanda, 1, 佐藤 | Japan, Tokyo, Chiyoda, Otemachi, 1, 鈴木 | Japan, Tokyo, Chiyoda, Otemachi, 2, 伊藤 | Japan, Tokyo, Minato, Akasaka, 1, 橋本 | Japan, Tokyo, Minato, Akasaka, 2, 萩原'
    
    a = a.split(' | ')
    let obj = {}
    for(let y of a){
        y = y.split(", ")
        y = y.reduceRight((pre, cur) => {
            return {[cur]:pre}
        })
        console.log(y)
        Object.assign(obj, y)
    }
    console.log(obj)
    
[/code]


CC BY-SA 4.0
2019-12-02T14:46:19.170
61029
2019-12-03T03:46:28.687
2019-12-03T02:08:24.863
3060
32180
question
javascript
javascript 配列をカテゴリ化したい


オブジェクトを再帰的にマージする簡単な方法は思いつかなかったので、`mergeObjectOnto()`は地道なコードとなっています。

ツリーの末端でキーが衝突した場合はとりあえず配列化するようにしました。

実行結果:

[code]

    {
      "Japan": {
        "Tokyo": {
          "Chiyoda": {
            "Kanda": {
              "1": "佐藤"
            },
            "Otemachi": {
              "1": "鈴木",
              "2": "伊藤"
            }
          },
          "Minato": {
            "Akasaka": {
              "1": "橋本",
              "2": [
                "萩原",
                "田中"
              ]
            }
          }
        }
      }
    }
    
[/code]

[code]

    const source = 'Japan, Tokyo, Chiyoda, Kanda, 1, 佐藤 | ' +
        'Japan, Tokyo, Chiyoda, Otemachi, 1, 鈴木 | ' +
        'Japan, Tokyo, Chiyoda, Otemachi, 2, 伊藤 | ' +
        'Japan, Tokyo, Minato, Akasaka, 1, 橋本 | ' +
        'Japan, Tokyo, Minato, Akasaka, 2, 萩原 | ' +
        'Japan, Tokyo, Minato, Akasaka, 2, 田中';
    
    const rows = source.split(' | ');
    let obj = {};
    for (const row of rows) {
      const columns = row.split(", ");
      const nestedColumns = columns.reduceRight((pre, cur) => {
        return {[cur]:pre};
      });
      console.log(nestedColumns);
      mergeObjectOnto(nestedColumns, obj);
    }
    // 結果表示
    console.log(obj);
    document.querySelector('pre').textContent = JSON.stringify(obj, null, 2);
    
    function mergeObjectOnto(src, dest) {
      for (const key in src) {
        if (!dest.hasOwnProperty(key)) {
          dest[key] = src[key];
        } else if (!(src[key] instanceof Object) || !(dest[key] instanceof Object)) {
          // オブジェクトではないものが衝突した場合、とりあえず配列に詰めておく。
          if (dest[key] instanceof Array) {
            dest[key].push(src[key])
          } else {
            dest[key] = [dest[key], src[key]];
          }
        } else {
          mergeObjectOnto(src[key], dest[key]);
        }
      }
    }
[/code]

[code]

    pre {
      white-space: pre-wrap;
    }
[/code]

[code]

    <pre></pre>
[/code]


CC BY-SA 4.0
2019-12-03T03:46:28.687
61047
2019-12-03T03:46:28.687
3475
61029
answer