首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函数,该函数将从SQL DB返回的行分组。

函数,该函数将从SQL DB返回的行分组。
EN

Code Review用户
提问于 2014-11-05 13:04:45
回答 2查看 36关注 0票数 4

下面包含了从SQL数据库返回的数据集,因为除了一个属性"name_alt“之外,您可以看到所有数据都保持不变。

代码语言:javascript
复制
[{
    "language_id": "tly",
    "language_name": "Talysh",
    "speakers_native": 800000,
    "total_speakers": 912000,
    "name_alt": "Taleshi",
    "country_main": "az"
}, {
    "language_id": "tly",
    "language_name": "Talysh",
    "speakers_native": 800000,
    "total_speakers": 912000,
    "name_alt": "Talish",
    "country_main": "az"
}, {
    "language_id": "tly",
    "language_name": "Talysh",
    "speakers_native": 800000,
    "total_speakers": 912000,
    "name_alt": "Talishi",
    "country_main": "az"
}, {
    "language_id": "tly",
    "language_name": "Talysh",
    "speakers_native": 800000,
    "total_speakers": 912000,
    "name_alt": "Talysh",
    "country_main": "az"
}, {
    "language_id": "tly",
    "language_name": "Talysh",
    "speakers_native": 800000,
    "total_speakers": 912000,
    "name_alt": "Talyshi",
    "country_main": "az"
}, {
    "language_id": "lez",
    "language_name": "Lezghian",
    "speakers_native": 171400,
    "total_speakers": 428400,
    "name_alt": "Kiurinsty",
    "country_main": "ru"
}, {
    "language_id": "lez",
    "language_name": "Lezghian",
    "speakers_native": 171400,
    "total_speakers": 428400,
    "name_alt": "Kiurinty",
    "country_main": "ru"
}, {
    "language_id": "lez",
    "language_name": "Lezghian",
    "speakers_native": 171400,
    "total_speakers": 428400,
    "name_alt": "Lezghi",
    "country_main": "ru"
}]

我希望将所有的name_alts组合成一个数组,所以我的数据如下所示:

代码语言:javascript
复制
[{
    "language_id": "tly",
    "language_name": "Talysh",
    "speakers_native": 800000,
    "total_speakers": 912000,
    "name_alt": ["Talesh", "Taleshi", "Talish", "Talishi", "Talyshi"],
    "country_main": "az"
}, {
    "language_id": "lez",
    "language_name": "Lezghian",
    "speakers_native": 171400,
    "total_speakers": 428400,
    "name_alt": ["Kiurinsty", "Kiurinty", "Lezghi", "Lezgi", "Lezgian", "Lezgin"],
    "country_main": "ru"
}]

我编写了这个函数,它接受数组,映射并过滤它,以返回我需要的数据集。它很有效,但我担心它不是很好的表演。它接受我想要压缩的数组(array)、我想按其分组的属性(mappedProperty)、对每一行都应该保持唯一的属性(uniqueProperty),以及应该从分组属性集(mainProperty)中排除的属性。

你能复习一下吗?

代码语言:javascript
复制
function reduceRows(array, mappedProperty, uniqueProperty, mainProperty) {
    var currentUniqueProp;
    var objToReturn;
    var mappedObj = _.map(array, function(obj) {
            // we're grouping by the unique property (i.e. an ID), so if we have a new
            // unique property, we clone the object, and start adding the
            // mapped property (i.e. alternative names for a language) to the array
            //usage: u.reduceRows(data.data.languages, "name_alt", "language_id", "language_name")
            if (obj[uniqueProperty] != currentUniqueProp) {
                objToReturn = _.clone(obj)
                objToReturn[mappedProperty] = [obj[mappedProperty]]
                currentUniqueProp = obj[uniqueProperty]
            } else {
                // sometimes the grouped property has a value which is the same as the main property
                // i.e. the language_name is also included in the list of name_alts
                // We want to avoid this duplication
                if (obj[mappedProperty] != obj[mainProperty]) {
                    objToReturn[mappedProperty].push(obj[mappedProperty])
                }
            }
            return objToReturn;
        })
    var filteredObj = _.filter(mappedObj, function(obj) {
        //this function ensures that only one entry for each unique property
        //is returned
        if (obj[uniqueProperty] == currentUniqueProp) {
            return false
        } else {
            currentUniqueProp = obj[uniqueProperty]
            return true
        }
    })
    return filteredObj
}
EN

回答 2

Code Review用户

回答已采纳

发布于 2014-11-05 15:32:20

有几件事:

  • 你不需要下划线。节点支持ECMAScript 5特性,如Array.prototype.mapArray.prototype.filter。将_.map(array, function)替换为array.map(function)等。
  • 命名您的内联函数。这对可读性更好,如果代码出错,如果不知道哪个匿名函数,就不会得到(anonymous function)
  • map用于将一个数组映射到另一个数组,如果您只想迭代一个数组并运行一个函数,则需要Array.prototype.forEach

我会采取另一种方法来做这件事。

  1. 计算出唯一的条目(除了name_alt)
  2. 迭代每个唯一条目的“组”,并将每个reduce分别迭代到单个对象。
  3. 将每个新创建的对象推入一个新数组中。

以下是我的看法:

代码语言:javascript
复制
// ## Get an array of language_ids to be used as a unique key. 
// ## I'm assuming here that if language_id is equal, the rest (aside from name_alt) is also equal.
var uniqueKeys = data
    .map(function pluckLanguageId(obj) { return obj.language_id; }) 
    //Now your array looks like ["a", "a", "a", "b", "b" ,"b"]
    .filter(function makeUnique(language, index, array) { return array.indexOf(language) === index; }); 
    //Now your array looks like ["a", "b"]

// ## Map each of the keys to a formatted object:
var result = uniqueKeys.map(function mapKeysToFormattedObjects(key) {
    //Take the entire data array
    return data
        //Filter it by language_id
        .filter(function getOnlyDataWithKey(item) { return item.language_id === key; }) 
        //Then combine it into one object
        .reduce(function combineToOneObject(previous, current) { 
            if (typeof(previous.name_alt) === "string") { //In this first object, the name_alt would be a string.
                previous.name_alt = [previous.name_alt]; //So make it into an array!
            }
            previous.name_alt.push(current.name_alt); //Push the current name_alt into the previous one.
            return previous;
        }); //Result is an object with all of the name_alts in an array
})

这是假设原始数据在data变量中。如果有什么你不明白的,请告诉我,我会尽力解释的。

注意我是如何链接我的调用映射,过滤和减少。mapfilter都返回一个数组,因此对这个新处理的数组执行链式调用。

一种更理想的编写方法是将所有的东西分解成函数,然后有一个oneliner:

代码语言:javascript
复制
function pluckLanguageId(obj) { return obj.language_id; }
function makeUnique(language, index, array) { return array.indexOf(language) === index; }

function mapKeysToFormattedObjects(key) {
    return data
        .filter(function getOnlyDataWithKey(item) { return item.language_id === key; }) 
        .reduce(function combineToOneObject(previous, current) { 
            if (typeof(previous.name_alt) === "string") { //In this first object, the name_alt would be a string.
                previous.name_alt = [previous.name_alt]; //So make it into an array!
            }
            previous.name_alt.push(current.name_alt); //Push the current name_alt into the previous one.
            return previous;
        }); //Result is an object with all of the name_alts in an array
}

var result = data.map(pluckLanguageId).filter(makeUnique).map(mapKeysToFormattedObjects);
//One liner!

这段代码可以通过返回函数和诸如此类的函数来进一步改进,但是以第一个例子作为参考。

票数 2
EN

Code Review用户

发布于 2014-11-05 14:17:23

因为javascript有一个else if语句,所以您应该使用它来删除一个级别的缩进。

代码语言:javascript
复制
if (obj[uniqueProperty] != currentUniqueProp) {
    objToReturn = _.clone(obj)
    objToReturn[mappedProperty] = [obj[mappedProperty]]
    currentUniqueProp = obj[uniqueProperty]
} else if (obj[mappedProperty] != obj[mainProperty]) {
    // sometimes the grouped property has a value which is the same as the main property
    // i.e. the language_name is also included in the list of name_alts
    // We want to avoid this duplication

    objToReturn[mappedProperty].push(obj[mappedProperty])
}  

underscore滤波方法可以简化为

代码语言:javascript
复制
var filteredObj = _.filter(mappedObj, function(obj) {
    //this function ensures that only one entry for each unique property
    //is returned
    if (obj[uniqueProperty] == currentUniqueProp) {
        return false
    }
    currentUniqueProp = obj[uniqueProperty]
    return true
})

如果条件的计算结果为true,则方法将返回,因此不需要else

您应该始终在需要变量的地方声明它们。所以var objToReturn应该在这里声明

代码语言:javascript
复制
var mappedObj = _.map(array, function(obj) {
        var objToReturn;
        // we're grouping by the unique property 
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/68964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档