我正在尝试获取嵌套对象数组中每个键的总和和平均值,如下所示:
var data = [
{department:'Electro',quant:{M:30, T:20, W:51, R:22, F:35 }},
{department:'Beauty'',quant:{M:50, T:32, W:75, R:61, F: 45}},
{department:'Apparel'',quant:{M:62, T:42, W:135, R: 82, F:89}},
{department:'Misc',quant:{M:89, T:54, W:103, T:94, F:90}}
];
所以我需要分别对每个部门的总和。即sum = {'Elecro':158,'Beauty':263}
我使用的是汇总方法,但examples不适用于嵌套数组。
var deptSum = d3.nest()
.key(function(d) { return d.dept; })
.rollup(function(v) { return {
count: v.length,
total: d3.sum(v, function(d) {return d.quant; }),
avg: d3.mean(v, function(d) {return d.quant; })
}; })
.entries(data)
的console.log(JSON.stringify(deptSum))
但是给我0的总和。
答案 0 :(得分:1)
你甚至不需要d3,这是一个纯粹的js解决方案:
{"Electro":158,"Beauty":263,"Apparel":410,"Misc":376}
会给你import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import com.sun.prism.impl.Disposer.Record;
import javax.swing.JButton;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import javax.swing.JTextField;
import javax.swing.JComboBox;
import javax.swing.DefaultComboBoxModel;
import traitement.CustomRenderer;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class TestSort extends JFrame implements ActionListener{
private JTable table1;
private JButton btnSort;
private int selectedCombCriteria=-1;
private JComboBox combCriteria;
private Boolean showSelection=false;
public static void main(String[] args) {
// TODO Auto-generated method stub
TestSort ts=new TestSort();
ts.setVisible(true);
}
TestSort()
{
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation(dim.width/2-this.getSize().width/2, dim.height/2-this.getSize().height/2);
setSize(new Dimension(439, 325));
setPreferredSize(new Dimension(600,400));
JPanel pt=new JPanel();
getContentPane().add(pt);
pt.setLayout(null);
combCriteria = new JComboBox();
combCriteria.setModel(new DefaultComboBoxModel(new String[] {"Age", "Score"}));
combCriteria.setSelectedIndex(0);
combCriteria.setBounds(115, 205, 67, 20);
combCriteria.addActionListener(this);
pt.add(combCriteria);
btnSort = new JButton("Sort");
btnSort.addActionListener(this);
btnSort.setBounds(324, 204, 89, 23);
pt.add(btnSort);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(20, 41, 393, 127);
pt.add(scrollPane);
table1 = new JTable();
SortModel sm=new SortModel();
table1.setModel(sm);
table1.setBounds(50, 26, 329, 130);
scrollPane.setViewportView(table1);
table1.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent event) {
SortModel.selectedRecord=((SortModel)table1.getModel()).getRowAt(table1.getSelectedRow());
showSelection=true;
}
});
table1.setDefaultRenderer(Object.class, new DefaultTableCellRenderer()
{
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
final Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
c.setBackground(row==0?Color.YELLOW:isSelected&&showSelection?Color.lightGray:Color.white);
return c;
}
});
JLabel lblSelectARow = new JLabel("Select a row to keep at the top and sort using one of the sorting criteria");
lblSelectARow.setFont(new Font("Traditional Arabic", Font.PLAIN, 14));
lblSelectARow.setHorizontalAlignment(SwingConstants.CENTER);
lblSelectARow.setBounds(20, 11, 393, 23);
pt.add(lblSelectARow);
JLabel lblSortCreteria = new JLabel("Sorting criteria:");
lblSortCreteria.setBounds(20, 208, 96, 14);
pt.add(lblSortCreteria);
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==btnSort)
if(SortModel.selectedRecord!=null)
{
((SortModel)table1.getModel()).sort(selectedCombCriteria);
table1.repaint();
showSelection=false;
}
if(e.getSource()==combCriteria)
{
selectedCombCriteria=combCriteria.getSelectedIndex();
}
}
}
class SortModel extends AbstractTableModel
{
public SortModel(){
data=fillOnce();
}
private String[] columns = {"First Name", "Last Name", "Profession", "Age","Score","Comment"};
public List<MyDataRecord> data=new ArrayList<MyDataRecord>();
public static MyDataRecord selectedRecord;
@Override
public int getRowCount() {
// TODO Auto-generated method stub
return data.size();
}
@Override
public String getColumnName(int column) {
return columns[column];
}
@Override
public int getColumnCount() {
return columns.length;
}
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return data.get(rowIndex).getfName();
case 1:
return data.get(rowIndex).getlName();
case 2:
return data.get(rowIndex).getProfession();
case 3:
return data.get(rowIndex).getAge();
case 4:
return data.get(rowIndex).getScore();
case 5:
return data.get(rowIndex).getComment();
default:
throw new IllegalArgumentException();
}
}
public MyDataRecord getRowAt(int rowIndex)
{
return data.get(rowIndex);
}
//sorting method
public void sort(int sort)
{
//sort
Collections.sort(data, new Comparator<MyDataRecord>() {
public int compare(MyDataRecord object1, MyDataRecord object2) {
if(sort!=1)
return Integer.compare(object1.getAge(), object2.getAge());
else
return Integer.compare(object1.getScore(), object2.getScore());
}
});
//then remove he selected element
data.remove(selectedRecord);
//put the selected element on the top of the list
if(selectedRecord!=null)
{
data.add(0, selectedRecord);
}
}
public List<MyDataRecord> fillOnce()
{
List<MyDataRecord> tempList=new ArrayList<MyDataRecord>();
Random r = new Random();
for(int i=1;i<=6;i++)
{
MyDataRecord mdr=new MyDataRecord("FNtest"+i, "LNtest"+i, "PROFtest"+i, "COMtest"+i, r.nextInt(100-1) + 1, r.nextInt(100-1) + 1);
tempList.add(mdr);
}
return tempList;
}
}
class MyDataRecord{
private String fName,lName,profession,comment;
private int age,score;
public MyDataRecord(String fName, String lName, String profession,
String comment, int age, int score) {
super();
this.fName = fName;
this.lName = lName;
this.profession = profession;
this.comment = comment;
this.age = age;
this.score = score;
}
public String getfName() {
return fName;
}
public void setfName(String fName) {
this.fName = fName;
}
public String getlName() {
return lName;
}
public void setlName(String lName) {
this.lName = lName;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}
答案 1 :(得分:1)
有一种D3方法可以获得汇总中的总和(以及平均值)。但问题是,d3.sum
和d3.mean
都需要数组,但quant
只是一个对象:
quant: {M:30, T:20, W:51, R:22, F:35 };
解决方案:使用D3方法获取名为d3.values
的属性值。根据{{3}},它:
返回一个包含指定对象(关联数组)的属性值的数组。
因此,您的rollup
应为:
.rollup(function(v) {
return {
count: v.length,
total: d3.sum(d3.values(v[0].quant)),
avg: d3.mean(d3.values(v[0].quant))
};
})
这是一个演示:
var data = [
{department:'Electro',quant:{M:30, T:20, W:51, R:22, F:35 }},
{department:'Beauty',quant:{M:50, T:32, W:75, R:61, F: 45}},
{department:'Apparel',quant:{M:62, T:42, W:135, R: 82, F:89}},
{department:'Misc',quant:{M:89, T:54, W:103, T:94, F:90}}
];
var deptSum = d3.nest()
.key(function(d) { return d.department; })
.rollup(function(v) { return {
count: v.length,
total: d3.sum(d3.values(v[0].quant)),
avg: d3.mean(d3.values(v[0].quant))
}; })
.entries(data)
console.log(deptSum)
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;