Подчеркивание сорвать двумерный массив

Первый раз, используя подчеркивание, и я застрял и не могу найти пример.

Мои данные:

[{
        "store_name": "Store 1",
        "franchisee_id": "id01",
        "dish_menu": "Breakfast",
        "dish_count": "17"
    }, {
        "store_name": "Store 1",
        "franchisee_id": "id01",
        "dish_menu": "Light Meals",
        "dish_count": "7"
    }, {
        "store_name": "Store 1",
        "franchisee_id": "id01",
        "dish_menu": "Sandwiches",
        "dish_count": "12"
    }, {
        "store_name": "Store 2",
        "franchisee_id": "id02",
        "dish_menu": "Breakfast",
        "dish_count": "7"
    },
        ............
]

Я сумел (с некоторой помощью отсюда) вывести store_name с помощью следующей цепочечной команды, а затем поместите ее в HTML-оператор, который я строю:

var stores = _.chain(json).pluck("store_name").sort().uniq(true).value();
var tempHTML = "";

stores.forEach(function (entry) {
    tempHTML = tempHTML + '<option value="' + entry + '">' + entry + '</option>';
});

Но я пытаюсь соответствовать franchisee_id к отчетливому store_name и по сути построить мой HTML, как показано ниже:

stores.forEach(function (entry) {
    tempHTML = tempHTML + '<option value="' + FRANCHISEE_ID + '">' + STORE_NAME + '</option>';
});

Есть ли способ _.pluck значение для franchisee_id, используя значение store_name? Между этими двумя полями существует соотношение 1:1, поэтому даже получение первого найденного franchisee_id вполне подойдет. Спасибо!

2 ответа

Решение

Вы можете сделать что-то вроде этого, чтобы получить ваши пары id/name в желаемом порядке:

var map_id_to_name = function(m, o) {
    m[o.franchisee_id] = o.store_name;
    return m;
};
var arrayify = function(name, id) {
    return [ name, id ];
};
var stores = _(data).chain()
                    .reduce(map_id_to_name, { })
                    .map(arrayify)
                    .sortBy(_.first)
                    .value();

Демо: http://jsfiddle.net/ambiguous/9xxS6/

Это даст вам массив массивов в stores что вы можете вращаться, чтобы построить свой <option>s; stores будет выглядеть так:

[
    [ "Store 1", "id01" ],
    [ "Store 2", "id02" ],
    ...
]

Название магазина будет в первой записи внутренних массивов, а идентификатор франшизы - во второй. Все это будет отсортировано по названию магазина. Если вы хотите сортировать без учета регистра, вы можете .sortBy(function(a) { return a[0].toLowerCase() }) вместо.

reduce(map_id_to_name, { }) собирает пары уникальных идентификаторов / имен, используя объект для автоматического обеспечения уникальности (в конце концов, ключи в объекте уникальны). затем map(arrayify) преобразует объект в массив массивов, чтобы вы могли сортировать вещи. Вместо этого вы могли бы использовать массив объектов, это было бы небольшим изменением map а также sortBy звонки.

Другой подход, извлекая нужную информацию из объектов и затем фильтруя полученный массив для получения уникальных объектов:

var stores = _(data).chain()

// convert each object to {store_name: ..., franchisee_id: ...}
.map(function(m) {
    return _.pick(m, "store_name", "franchisee_id");
})

//keep one of each
//can be shortened to .uniq(_.property('franchisee_id'))
.uniq(function(m) {
    return m.franchisee_id;
})

//sort by name
.sortBy("store_name")

//and get the array
.value();

Ваш окончательный массив будет выглядеть так

[
    {store_name: "Store 1", franchisee_id: "id01"},
    {store_name: "Store 2", franchisee_id: "id02"}
]

И демо, чтобы играть с http://jsfiddle.net/mr82s/


И с небольшим _.mixin магия, вы могли бы еще сгущать его

_.mixin({
    properties: function() {
        var args = _.toArray(arguments);
        return function(obj) {
            return _.pick(obj, args);
        };
    }
});

var stores = _(data).chain()
.map(_.properties("store_name", "franchisee_id"))
.uniq(_.property('franchisee_id'))
.sortBy("store_name")
.value()

http://jsfiddle.net/nikoshr/mr82s/1/

Другие вопросы по тегам