Javascript - 如何根据第二个数组的顺序比较和排序一个数组?

时间:2017-04-23 20:20:23

标签: javascript arrays sorting

如果我有一堆包含任何旧帖子的数组:

[
    {
        id: 1,
        parent: 0
    },
    {
        id: 4,
        parent: 1
    },
    {
        id: 2,
        parent: 1
    },
    {
        id: 3,
        parent: 0
    },
    {
        id: 5,
        parent: 3
    }
]

但是,另一个数组根据第一个数组的ID确定第一个数组的结构:

[
    {
        id: 1,
        name: "first parent post",
        indent: 0
    },
    {
        id: 4,
        name: "first child of first parent post",
        indent: 1
    },
    {
        id: 2,
        name: "second child of first parent post",
        indent: 1
    },
    {
        id: 3,
        name: "second parent post",
        indent: 0
    },
    {
        id: 5,
        name: "first child of second parent post",
        indent: 1
    }
]

对这些进行排序的最有效方法是什么,以便第一个数组按第二个数组排序?

我希望结果数组看起来像这样:

int playersAmount, i;

printf("How many players are there?");
scanf("%i", &playersAmount);

for (i = 1; i <= playersAmount; i++) {
    struct players //player(i);
}

3 个答案:

答案 0 :(得分:1)

您可以按索引对数据数组进行排序,然后按顺序数组排序;

要获得缩进,您必须跟踪父上游的缩进并添加一个:

#lang racket/gui

(define main-frame
  (new frame% (label "Choose Your Fate")
       (width 250)))

(define button-panel
  (new vertical-panel% (parent main-frame)))

(define (clear-children)
  (send button-panel change-children (λ(x) '())))

; ((a b ...) ...) -> ((0 a b ...) (1 ...) ...)
(define (index-choices list-of-choices)
  (for/list ((choice list-of-choices)
             (index (in-naturals)))
    (cons index choice)))

(define choices
  (index-choices '((hello)
                   (yes no)
                   (one two three)
                   (left right up down))))

; all choices are done
; display the choices and offer a restart
(define (finish-choices)
  (clear-children)
  (new message% (parent button-panel)
       (label (responses->string responses)))
  (new button% (parent button-panel)
       (label "Restart")
       (callback (λ(b e)
                   (make-choice-buttons choices)))))


; ((index choices ...) rest...) -> index + (choices ...) (rest...)
(define (unpack choices)
  (let ((head (first choices)))
    (values (first head) (rest head) (rest choices))))

; #(symbols ...)
(define responses (build-vector (length choices) (λ(x) #f)))

; #(symbols ...) -> "symbols ..."
(define (responses->string res)
  (string-join
   (for/list ((val (in-vector res)))
     (symbol->string val))))

(define (make-callback index choice rest)
  (define (call button event)
    ;grab the response
    (vector-set! responses index choice)
    ; add next choices, or finish
    (if (empty? rest)
        (finish-choices)
        (make-choice-buttons rest)))
  call)
; ((index choices ...) rest...) -> buttons per choice
(define (make-choice-buttons choices)
  (define-values (this-index this-choice remaining-choices)
    (unpack choices))
  (clear-children)
  (for ((c this-choice))
    (new button%
         (parent button-panel)
         (label (symbol->string c))
         (callback (make-callback this-index c remaining-choices)))))

(make-choice-buttons choices)
(send main-frame show #t)

答案 1 :(得分:1)

您需要先生成一个包含依赖项的树,然后为原始数组的所有项呈现缩进。

此提案也适用于未分类的数据/关系。

function getDataWithIndent(data, relation) {
    var hash = Object.create(null),
        tree = function (data, root) {
            var r = [], o = {};
            data.forEach(function (a) {
                a.children = o[a.id] && o[a.id].children;
                o[a.id] = a;
                if (a.parent === root) {
                    r.push(a);
                } else {
                    o[a.parent] = o[a.parent] || {};
                    o[a.parent].children = o[a.parent].children || [];
                    o[a.parent].children.push(a);
                }
            });
            return r;
        }(relation, 0),
        result = [];

    data.forEach(function (a) {
        hash[a.id] = a;
    });
    tree.forEach(function iter(indent) {
        return function (a) {
            hash[a.id].indent = indent;
            result.push(hash[a.id]);
            Array.isArray(a.children) && a.children.forEach(iter(indent + 1));
        };
    }(0));
    return result;
}

var data = [{ id: 1, name: "first parent post" }, { id: 2, name: "second child of first parent post" }, { id: 3, name: "second parent post" }, { id: 4, name: "first child of first parent post" }, { id: 5, name: "first child of second parent post" }],
    relation = [{ id: 1, parent: 0 }, { id: 4, parent: 1 }, { id: 2, parent: 1 }, { id: 3, parent: 0 }, { id: 5, parent: 3 }],
    result = getDataWithIndent(data, relation);
  
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:-1)

对于排序,将第一个数组转换为Map,然后将信息从中拉入第一个数组。

function combineArrays(arr1, arr2) {
    let names = new Map(arr1.map(({id, name}) => [id, name]));
    return arr2.map(({id, parent}) => ({id: id, name: names.get(id), parent: parent}));
}

这将按您想要的顺序为您提供nameidparent。计算indent留给读者一个练习(或者应该是一个不同的问题)。