求一个数组按属性分组的方法

var arr = [

{city: "上海", location: "浦东"},
{city: "上海", location: "静安"},
{city: "北京", location: "内环"},
{city: "北京", location: "五环"},
{city: "苏州", location: "苏州"},

];

arr按city分组的方法,谢谢!

返回一个数组
[
{city:"",location:[]}
]

阅读 17.1k
6 个回答
// 获取 {} 结构
const mapCityLoction = function(arr) {
    let cities = {};
    arr.forEach((address, index) => {
        let locations = cities[address.city] || [];
        locations.push(address.location);
        cities[address.city] = locations;
    })
    return cities;
}

// forEach 获取 [ {city: , location}] 结构
const mapCityLoction_new = function() {
    let newArr = [];
    arr.forEach((address, i) => {
        let index = -1;
        let alreadyExists = newArr.some((newAddress, j) => {
            if (address.city === newAddress.city) {
                index = j;
                return true;
            }
        });
        if (!alreadyExists) {
            newArr.push({
                city: address.city,
                location: [address.location]
            });
        } else {
            newArr[index].location.push(address.location);
        }
    });
    return newArr;
};

// reduce 获取 [ {city: , location}] 结构
const mapCityLoction_lastest = function() {
    return arr.reduce( (prev, current) => {
        let index = -1;
        prev.some((address, i) => {
            if (address.city === current.city) {
                index = i;
                return true;
            }
        });
        if (index > -1) {
            prev[index].location.push(current.location);
        } else {
            prev.push({
                city: current.city,
                location: [current.location]
            });
        }
        return prev;
    }, [])
};
arr.reduce(function (pre, current, index) {
  pre[current.city] = pre[current.city] || []
  pre[current.city].push(current.location)
  return pre
}, {})

结果

Object {上海: Array[2], 北京: Array[2], 苏州: Array[1]}

题主在提问一个小时之后,修改了问题,原问题可以通过 sf 的历史版本功能查看。
题主修改的内容,无非是修改了一下想要的数据格式,我并不打算修改原来的答案,只是想简单说几句。
其实题主的问题,本来非常简单,我相信如果认真学习了 JavaScript 的数组、对象及循环的话,不会写不出来,但考虑到有些入门的童鞋可能确实需要一些代码示例来理解某些问题,我还是以代码的形式给出了回答,确实是非常简单的几行代码,希望题主能够学习理解其中的思想。
而我本人对直接给出代码的回答其实也是蛮反感的,一段特定的代码只能解决一类特定的问题,而深入了解一下代码背后的思路、原理才是自主解决问题的关键。
我个人也将 sf 看作一个知识库,而非一个代码库,我想你们应该能够理解其中的区别。
然而我发现太多的人将这里当作一个代码库来使用,他们感觉来这里解决问题要比去查阅资料,使用搜索引擎方便太多:描述完问题,就等着答案送上门来。
然而我想说,如果真的这样使用一个问答社区,你们将永远得不到成长,而只是一个低级的代码机器。
吐槽完毕,此问题我先踩为敬。


以下为原答案

var cities = {};

for (var i = 0; i < arr.length; i++) {
    if (cities[arr[i].city]) {
        cities[arr[i].city].push(arr[i].location)
    }
    else {
        cities[arr[i].city] = [arr[i].location]
    }
}
var cities = {};
arr.forEach(function(item, index, array) {
    cities[item.city] = cities[item.city] || [];
    cities[item.city].push(item);
});

在处理这种结构的时候,感觉就有点给自己找麻烦。
自己都觉得处理起来比较麻烦的时候,就可以思考一下有什么方法可以更好的解决,何必写程序来难为自己呢。

以上内容为玩笑,勿介意。

下面提供一种处理方案:

function getCityData(data){
   var res={};
    for(var i=0;i<data.length;i++){
        var d=data[i];
        var city=d['city'];
        res[city]=res[city]||[];
        res[city].push(d);
    }
    //
    return res;
}

只是提供一种思路,非最终解决方案!

题主是想查找出某个城市的所有项么?大概实现如下

function search(str) {
    var res = [];
    for(var i in arr) {
        if (arr[i].city == str) {
            res.push(arr[i]);
        }
    }
    return res;
}

console.log(search("上海"));
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏