javascript - 物化路径中的对象

标签 javascript materialized-path-pattern

我正在尝试从物化类别路径数组创建类别对象数组。

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 只能出现一次,因为所有其他类别都只是子类别。但是,领导力应该出现两次,因为两者的结构不同。

当你检查 fiddle 时 http://jsfiddle.net/9uC9Z/ 您可以看到 Business 存在 4 次。

如何解决这个问题?

如果生成的代码非常复杂,我真的很感激代码注释。

编辑: data 数组中的具体化路径字符串反射(reflect)了书籍的类别层次结构。一个例子是:

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

这仅代表一本书。我现在想为每个类别创建一个 MongoDB 文档。上面的示例书将生成三个类别对象(业务、管理、领导力)。但是,如果类别(或子类别)对象/文档已经存在,我不需要创建另一个。 因此,result代表我将存储在 MongoDB 集合中的类别对象。 (我将添加类别之间的关系,但这不是当前问题的一部分。)

最佳答案

函数式方法:

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) 来实现对象相等。您可以在这里阅读更多相关信息How to determine equality for two JavaScript objects?

关于javascript - 物化路径中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21366735/

相关文章:

php - 从 PHP 将数据集传递给 JavaScript 验证

javascript - 如何读取react应用程序中当前的URL

javascript - MediaRecorder API - 自动录制

javascript - mongoose & ember,记录拒绝原因: typeerror

javascript - 了解在处理子元素(而不是属性)时如何使用 prop()

ruby - 从物化路径构建树

mysql - 物化路径按日期+路径排序

javascript - 从物化路径构建 JSON 树

python - 声明式 SQLAlchemy 中的具体化路径关系

tree - Riak 存储树结构