1

具体化されたカテゴリ パスの配列からカテゴリ オブジェクトの配列を作成しようとしています。

var data = [
    'Business / Finance',
    'Business / Management',
    'Business / Management / Leadership',
    'Business / Team / Leadership'
];

// Expected results:
var result = [
    { name: 'Business', trail: null, path: 'Business' },
    { name: 'Finance', trail: 'Business', path: 'Business / Finance' }, 
    { name: 'Management', trail: 'Business', path: 'Business / Management' },
    { name: 'Leadership', trail: 'Business / Management', path: 'Business / Management / Leadership' }, 
    { name: 'Team', trail: 'Business', path: 'Business / Team / Leadership' },
    { name: 'Leadership', trail: 'Business / Team', path: 'Business / Team / Leadership' }
];

ご覧のとおり、Business他のすべてはサブカテゴリにすぎないため、一度だけ存在する必要があります。ただし、Leadership両方とも異なる構造にあるため、2 回存在する必要があります。

フィドルhttp://jsfiddle.net/9uC9Z/をチェックアウトすると、それBusinessが 4 回存在することがわかります。

どうすれば問題を解決できますか?

結果のコードが非常に複雑な場合は、コード コメントをいただければ幸いです。

編集:配列 内の実体化されたパス文字列は、data本のカテゴリ階層を反映しています。例は次のとおりです。

{
    title: 'Leadership 101',
    author: 'John Smith',
    category: 'Business / Management / Leadership'
}

それはちょうど1冊の本を表しています。ここで、すべてのカテゴリに対して 1 つの MongoDB ドキュメントを作成したいと考えています。上記のサンプル本は、3 つのカテゴリ オブジェクト (ビジネス、管理、リーダーシップ) を生成します。ただし、カテゴリ (またはサブカテゴリ) オブジェクト/ドキュメントが既に存在する場合は、別のものを作成する必要はありません。 resultしたがって、MongoDB コレクション内に格納するカテゴリ オブジェクトを表します。(カテゴリ間の関係を追加しますが、それは現在の問題の一部ではありません。)

4

1 に答える 1

0

機能的アプローチ:

function extract (path, trail) {
    if (path.length === 0) {
        return [];
    }
    var item = {
        name: path[path.length - 1],
        trail: trail.length === 0 ? null : trail.join(' / '),
        path: path.join(' / ')
    };
    var result = extract(path.slice(0, -1), path.slice(0, -2)).concat([item]);
    return result;
}

function distinct (xs) {
    function eq (a, b) {
        return JSON.stringify(a) === JSON.stringify(b);
    }

    function contains (xs, x) {
        for (var i = xs.length - 1; i >= 0; i--) {
            if (eq(xs[i], x)) {
                return true;
            }
        }
        return false;
    }

    var result = [];
    for (var i = xs.length - 1; i >= 0; i--) {
        if (!contains(result, xs[i])) {
            result.push(xs[i]);
        }
    }
    return result;
}

var result = data.
  map(function(x) { return x.split(' / ') }).
  map(function(x) { return extract(x, x.slice(0, -1)) }).
  reduce(function(a, b) { return a.concat(b)});

result = distinct(result);

distinct関数をいくつかのライブラリからより堅牢なものに置き換えることができます。JSON.stringify(a) === JSON.stringify(b)また、他の場所での for object equality の使用には注意してください。詳しくは、2 つの JavaScript オブジェクトの等価性を判断する方法は?

于 2014-01-26T19:21:10.623 に答える