在下面的代码中,我将根据JSON响应创建一个“伪”数据帧,以实现类似Python的数据操作。
是否有比下面发布的方法更详细的方法?
基本上,我需要将对象数组放入单个对象中。所有对象都具有相同的结构。
<script>
//~ request API for data
function get_data(callback){
$.ajax({type:"GET",
url: "{% url 'explorer_api:list_activities' %}",
//~ success: function(data){
//~ console.log(data[1])},
success: callback,
headers: {'X-CSRFToken': '{{ csrf_token }}'},
});
}
//~ get data and process it
get_data(function(data) {
//create dataframe
function create_dataframe() {
var activities = data;
var df = {
number: [],
athlete: [],
start_date: [],
name: [],
country: [],
link: [],
segment_efforts:[],
distance: [],
average_speed: [],
};
for (i in activities) {
df.number.push(activities[i].number);
df.athlete.push(activities[i].athlete);
df.start_date.push(activities[i].start_date);
df.name.push(activities[i].name);
df.country.push(activities[i].country);
df.link.push(activities[i].link);
df.segment_efforts.push(activities[i].segment_efforts);
df.distance.push(activities[i].distance);
df.average_speed.push(activities[i].average_speed);
};
return df;
};
df = create_dataframe()
console.log(df);
});
</script>
答案 0 :(得分:0)
您可以使用另一个for-in循环遍历对象的属性,而不用写出每一行。
for(i in activities) {
for(var prop in df) {
df[prop].push(activities[i][prop]);
}
}
我还建议使用传统的for循环或.forEach()之类的其他方法来遍历activities
,因为for-in是not recommended for arrays。
答案 1 :(得分:0)
您可以使用Object.entries遍历对象中的键。示例:
var activities = [{ number: 1, test: 2 }, { number: 2, test: 3 }]
var df = {}
for (var activity of activities) {
for (var [key, value] of Object.entries(activity)) {
if (!df[key]) df[key] = []
df[key].push(value)
}
}
df // { number: [1,2], test: [2,3] }
答案 2 :(得分:0)
这里有扩大热液反应的种类。您可以通过遍历对象中的键并使用简单的reduce
和其中的forEach
来设置值,而不是对值进行硬编码,从而使其更具动态性。这是该代码:
const arr = [{id: 0, value: 'foo'},{id: 1, value: 'bar'},{id: 2, value: 'baz'}];
const obj = arr.reduce((initial, value, index) => {
const keys = Object.keys(value);
keys.forEach(key => {
if(!initial[key]) initial[key] = [value[key]];
else initial[key].push(value[key]);
});
return initial;
}, {});
console.log(obj)
就详细程度而言,这并没有太大变化,但我认为这是比您所提出的问题更好,更动态的实现方式。
答案 3 :(得分:0)
这是一种功能性(ES6)方法:
data.reduce((a,c) => { Object.keys(c).map(k => a[k] = a[k] ? [...a[k],c[k]] : [c[k]]); return a; }, {})
尽管与使用JavaScript的命令式方法相比,我不会押注任何性能提升。
[更新]
这是当务之急,它与上述功能“最接近”:
result = { }
for(var e of DATA){
for(var p in e){
if(result[p]) { result[p].push(e[p]) } else { result[p] = [e[p]] }
}
}
您可能已经注意到,我提出的解决方案对数组中的对象没有任何先入之见-就像具有相同的结构一样。这会为检查结果中的属性带来一些开销。
但是,正如我所怀疑的那样,并且在某些情况下已经注意到,从性能的角度来看,JavaScript的功能方面并没有得到真正的阐述。
但是我想看看自己,所以我在这里测试了以上两个片段:https://jsperf.com/ao-to-oa-imp-func/1
对于我来说,结果令人信服:功能代码比我的Chrome浏览器中的命令性代码慢93%,而在Firefox中则慢99%。