从另一个obseravableArray获取observableArray的唯一值

时间:2015-01-07 06:46:00

标签: arrays knockout.js unique ko.observablearray

我的数据如下:

    { mealName: "sandwich", price: 0 },
    { mealName: "lobster", price: 34.95 },
    { mealName: "whole zebra", price: 290 },
    { mealName: "whole zebra", price: 290 },
    { mealName: "sandwich", price: 290 },
    { mealName: "whole zebra", price: 290 }

我希望observableArray像:

{ mealName: "sandwich"},
{ mealName: "whole zebra"},
{ mealName: "lobster"}

我试图在jsFiddle中重现它,但出了点问题

2 个答案:

答案 0 :(得分:0)

唯一不必是一个可观察的数组,因为availableMeals不是一个可观察的数组,但是因为你问我使用了计算数据。

首先,我使用自定义排序功能对数组进行排序。我用concat创建了一个副本,因为我不想修改原始数组的顺序。然后我循环遍历排序的数组并删除任何重复项:

self.unique = ko.computed(function() {
     var sortedItems = self.availableMeals.concat().sort(function(left, right) { return left.mealName == right.mealName ? 0 : (left.mealName < right.mealName ? -1 : 1) });

     var meal;

     for (var i = 0; i < sortedItems.length; i++) {                 
         if (!meal || meal != sortedItems[i].mealName) {
             meal = sortedItems[i].mealName;
         }
         else {
             sortedItems.splice(i, 1);
             i--;
         }
     }

     return sortedItems;
});     

jsfiddle

答案 1 :(得分:0)

var uniqueMeals = ko.computed(function () {
    var uniqueMealNames = mealData().reduce(function(uniqueMeals, meal) {
        if(uniqueMeals.indexOf(meal.mealName) === -1) {
            uniqueMeals.push(meal.mealName);
        }
        return uniqueMeals;
    }, []);

    return uniqueMealNames.map(function(mealName) {
        return {mealName: mealName};
    });
});

一些建议:将唯一值存储在字符串数组中可能更好,而不是对象,即["sandwich", "whole zebra", "lobster"]。如果是这样,您可以从我上面的代码中删除最后一行。

另外,您可以考虑查看lodash库。使用lodash,这将是:

var uniqueMeals = ko.computed(function () {
    return _.unique(_.pluck(mealData, "mealName"));
})