简体   繁体   English

在javascript中过滤对象数组

[英]Filtering an array of Objects in javascript

I'm really new to JS, and I'm now stuck on a task, hope someone can guide me through it. 我对JS真的很陌生,现在被困在一个任务上,希望有人可以指导我完成任务。

I have an Array of Objects, like this one: 我有一个对象数组,像这样一个:

var labels = [
            // labels for pag 1
            {pageID:1, labels: [
                {labelID:0, content:[{lang:'eng', text:'Txt1 Eng'}, {lang:'de', text:'Txt1 De:'}]},
                {labelID:1, content:[{lang:'eng', text:'Txt 2 Eng:'}, {lang:'de', text:'Txt2 De:'}]},
                {labelID:2, content:[{lang:'eng', text:'Txt 3 Eng:'},{lang:'de', text:'Txt 3 De:'}]}
            ]},

            // labels for pag 2
            {pageID:2, labels: [
                {labelID:0, content:[{lang:'eng', text:'Txt1 Eng'}, {lang:'de', text:'Txt1 De:'}]},
                {labelID:1, content:[{lang:'eng', text:'Txt 2 Eng:'}, {lang:'de', text:'Txt2 De:'}]},
                {labelID:2, content:[{lang:'eng', text:'Txt 3 Eng:'},{lang:'de', text:'Txt 3 De:'}]}
            ]}
    ]

What I am trying to do is write a function to return me an array of labels (Objects) for a specific page and a specific lang. 我想要做的是编写一个函数,以向我返回特定页面和特定lang的标签数组(对象)。 By calling this function specifying pageID 1 and lang eng, I'm basically trying to build an array like this one: 通过调用指定pageID 1和lang eng的此函数,我基本上是在尝试构建一个像这样的数组:

var desideredArray = [
    {labelID:0, text:'Txt1 Eng'}, 
    {labelID:1, text:'Txt1 Eng'}, 
    {labelID:2, text:'Txt2 Eng'}
] 

Now, I'm trying to write the function to retrieve/build the new array: 现在,我试图编写函数来检索/构建新数组:

this.getLabelsForPageAndLang = function (numPage, lang) {
            // this part filters the main object and selects the object with pageID == numPage
        var result = labels.filter(function( obj ) {
            return obj.pageID == numPage;
        });

        var tempResult = result[0].labels;
        var desiredResults = [];  // here I want to store the new objects
        for (var i=0; i<tempResult.length; i++) {
            var simpleLabelObject = {};
            simpleLabelObject.labelID = tempResult[i].labelID;
            // simpleLabelObject.text = ?????

            results[i] = simpleLabelObject;
        }

        console.log (results);

    };

...but how can I access the right value (the one corresponding the lang selected) in the content property? ...但是如何在content属性中访问正确的值(对应于所选lang的值)?

You can use the same technique as the one used to keep the matching page: the filter method. 您可以使用与保留匹配页面相同的技术: filter方法。

this.getLabelsForPageAndLang = function (numPage, lang) {
        // this part filters the main object and selects the object with pageID == numPage
    var result = labels.filter(function( obj ) {
        return obj.pageID == numPage;
    });
    var contentFilter = function(obj){ return obj.lang === lang};

    var tempResult = result[0].labels;
    var desiredResults = [];  // here I want to store the new objects
    for (var i=0; i<tempResult.length; i++) {
        var simpleLabelObject = {};
        simpleLabelObject.labelID = tempResult[i].labelID;
        var matching = tempResult[i].content.filter(contentFilter);
        simpleLabelObject.text = matching[0].text;

        desiredResults[i] = simpleLabelObject;
    }

    console.log (desiredResults);

};

I didn't do bound checks because in your code you assumed there is always a matching element, but it would probably be wise to do it. 我没有进行边界检查,因为在您的代码中您假设总是有一个匹配的元素,但是这样做可能是明智的。

And if you want to avoid creating two closures each time the function is called, you can prototype an object for that: 而且,如果您希望避免在每次调用该函数时都创建两个闭包,则可以为此创建一个对象原型:

var Filter = function(numPage, lang) {
    this.numPage = numPage;
    this.lang = lang;
};

Filter.prototype.filterPage = function(obj) {
    return obj.pageID === this.numPage;
}

Filter.prototype.filterLang = function(obj) {
    return obj.lang === this.lang;
}

Filter.prototype.filterLabels = function(labels) {
    var result = labels.filter(this.filterPage, this);

    var tempResult = result[0].labels;
    var desiredResults = [];  // here I want to store the new objects
    for (var i=0; i<tempResult.length; i++) {
        var simpleLabelObject = {};
        simpleLabelObject.labelID = tempResult[i].labelID;
        var matching = tempResult[i].content.filter(this.filterLang, this);
        simpleLabelObject.text = matching[0].text;

        desiredResults[i] = simpleLabelObject;
    }

    return desiredResults;
}

console.log(new Filter(1, "eng").filterLabels(labels));

Just filter again: 再次过滤:

var getLabelsForPageAndLang = function (numPage, lang) {
    // this part filters the main object and selects the object with pageID == numPage
    var result = labels.filter(function (obj) {
        return obj.pageID == numPage;
    }); 
    var tempResult = result[0].labels;
    var desiredResults = []; // here I want to store the new objects
    for (var i = 0; i < tempResult.length; i++) {
        var simpleLabelObject = {};
        simpleLabelObject.labelID = tempResult[i].labelID;
        var lg = tempResult[i].content.filter(function (lg) {
            return lg.lang == lang;
        });
        simpleLabelObject.text = lg[0].text;

        desiredResults.push(simpleLabelObject);
    }

    console.log(desiredResults);

};

http://jsfiddle.net/9q5zF/ http://jsfiddle.net/9q5zF/

A rather 'safe' implementation for cases when pages have the same pageID and multiple contents with the same lang : 对于页面具有相同pageID和具有相同lang多个内容的情况,这是一个“安全”的实现:

this.getLabelsForPageAndLang = function(numPage, lang) {
    var result = [];
    var pages = labels.filter(function( obj ) {
        return obj.pageID === numPage;
    });
    for (var p = pages.length - 1; p >= 0; p--) {
        var page = pages[p];
        for(var i = page.labels.length - 1; i >= 0; i--) {
            var labelId = page.labels[i].labelID;
            for (var j = page.labels[i].content.length - 1; j >= 0; j--){
                if (page.labels[i].content[j].lang === lang) {
                    result.push({labelID: labelId, test: page.labels[i].content[j].text});
                }
            }
        }
    }    
    console.log(result);
}

Fiddle: http://jsfiddle.net/6VQUm/ 小提琴: http : //jsfiddle.net/6VQUm/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM