我不太擅长JS,但到目前为止还活了下来。我正在创建一个复杂的JS对象,并希望对其进行排序。对象的结构如下所示:
cart.attributes = [
{
Attribute,
Value
}
...
];
我正在创建一个独特的属性,告诉我3个由冒号任意分隔的东西:
(产品ID):(产品数量迭代器):(属性名称)
产品QTY迭代器只是意味着,如果我有3个相同的产品,那么凌晨3点我在谈论属性。然后每个属性都有一个值。
问题正如您从打印输出中看到的那样,没有任何组织。我想首先按(产品ID),然后是(QTY Iterator)对这些结果进行排序,然后按字母顺序按(名称)排序。
这是使用以下方法打印出来的对象,然后打印出结果。
使用打印结果的代码
$.each(cart.attributes, function(attr, value) {
console.log("Attr: "+attr);
console.log("Value: "+value);
});
结果
«Attr» 46913872:2:Size
«Value» 10
«Attr» 46913872:2:Hollow-to-Hem
«Value» 57"
«Attr» 46913872:1:Hips
«Value» 34"
«Attr» 46913872:2:Bust
«Value» 34"
«Attr» 46913872:2:Dress Color (hex)
«Value» #FFFFFF
«Attr» 46913872:2:Rush Cut
«Value» Super Rush Cut - 6 weeks
«Attr» 46913872:1:Extra Length
«Value» 5"
«Attr» 46913872:2:Hips
«Value» 34"
«Attr» 46913872:1:Waist
«Value» 29"
«Attr» 46913872:2:Waist
«Value» 23"
«Attr» 46913872:2:Dress Color (name)
«Value» White
«Attr» 46913872:1:Rush Cut
«Value» Super Rush Cut - 6 weeks
«Attr» 46913872:1:Sash Color (name)
«Value» Lipstick
«Attr» 46913872:2:Sash Color (hex)
«Value» #000000
«Attr» 46913872:1:Size
«Value» 14
«Attr» 46913872:1:Hollow-to-Hem
«Value» 58"
«Attr» 46913872:1:Bust
«Value» 35"
«Attr» 46913872:1:Sash Color (hex)
«Value» #B6064C
«Attr» 46913872:1:Dress Color (hex)
«Value» #F9C8D0
«Attr» 46913872:1:Dress Color (name)
«Value» Tea Rose
«Attr» 46913872:2:Extra Length
«Value» 5"
«Attr» 46913872:2:Sash Color (name)
«Value» Black
答案 0 :(得分:4)
从下面的评论中我可以更清楚地了解对象是什么。
假设对象看起来像这样:
cart.attributes = {
'46913872:2:Size' : 10,
'46913872:2:Hollow-to-Hem' : 57
// ...
}
由于它不是数组,因此无法排序。但是你可以将其分类打印出来。
在普通的旧javascript中你可以这样做:
// First get all keys:
var keys = [];
for (var n in cart.attributes) {
if (cart.attributes.hasOwnProperty(n)) {
keys.push(n);
}
}
// now sort the keys:
keys.sort(function(a,b){
attr_a = a.split(':');
attr_b = b.split(':');
// sort by product ID:
if (parseInt(attr_a[0],10) < parseInt(attr_b[0],10)) return -1;
if (parseInt(attr_a[0],10) > parseInt(attr_b[0],10)) return 1;
// sort by quantity:
if (parseInt(attr_a[1],10) < parseInt(attr_b[1],10)) return -1;
if (parseInt(attr_a[1],10) > parseInt(attr_b[1],10)) return 1;
// finally sort by name:
if (attr_a[2] < attr_b[2]) return -1;
if (attr_a[2] > attr_b[2]) return 1;
return 0;
})
// now print out the object in key-sorted-order:
for (var i=0; i<keys.length; i++) {
console.log("Attr: "+keys[i]);
console.log("Value: "+cart.attributes[keys[i]]);
}
答案 1 :(得分:3)
您应该能够基于对象属性对对象数组进行排序,方法是编写自定义排序函数,如下所示:
function customSortByPID(a,b) {
if (a.ProductID > b.ProductID)
{
return 1;
}
else if (a.ProductID < b.ProductID)
{
return -1;
}
return 0;
}
其中ProductID是对象的属性。你会这样称呼它:
myArray.sort(customSortByPID);
这至少应该让你开始研究如何编写自定义排序函数。请注意,JavaScript不是强类型的,可能会导致意外的排序行为(将int视为字符串)。
**免责声明**我没有测试上述任何一项,它只是在我的头顶。
答案 2 :(得分:3)
首先,理解对象的结构真的很难。这是它的样子吗?
[
{ "46913872:2:Size" : 10 },
{ "46913872:2:Hollow-to-Hem": 57},
{ "46913872:1:Hips" : "34"}, ...
]
看起来你想要它排序
[
{ "46913872:1:Hips" : "34"}, // all ids are the same here, but this index is 1
{ "46913872:2:Hollow-to-Hem": 57}, // index is 2 but Hollow comes before Size
{ "46913872:2:Size" : 10 },
]
如果我了解您的对象结构,以下解决方案是有效的。就像ThatSteveGuy所说,你可以将比较器传递给你的排序方法。由于对象太复杂了,这就是你要做的事情
attributes.sort(function(a, b){
// Make sense of your objects a and b. See the inner function defined below
var newA = improveObject(a);
var newB = improveObject(b);
if (newA.id > newB.id) { return 1; }
if (newA.id < newB.id) { return -1; }
// id is the same, check index
if (newA.index > newB.index) { return 1; }
if (newA.index < newB.index) { return -1; }
// index is the same, check name
if (newA.name > newB.name) { return 1; }
if (newA.name < newB.name) { return -1; }
// it's the same thing
return 0;
// Turns { "46913872:2:Size" : 10 }
// into {id: 46913872, index: 2, name: "Size", value: 10}
function improveObject(obj) {
for (var key in obj) {
var pieces = key.split(":");
return {
id: parseInt(pieces[0]),
index: parseInt(pieces[1]),
name: pieces[2],
value: obj[key];
};
}
}
});
但是,这个对象真的没有意义。我会敦促你重新思考它的结构。即使我没有完全理解你的对象(你应该列出对象的实际json),这个例子告诉你所有你需要知道的关于js排序的事情。
答案 3 :(得分:1)
如果要将多个值放在由分隔符分隔的字符串中,那么您首先忽略了创建对象的重点。结构应该是,
cart.attributes = [
{
attributes: {
id: "46913872",
quantityIterator: 2,
name: "Dress Color"
},
value: "57",
},
// repeat for each product
];
创建一个从编码字符串创建对象的函数是微不足道的。用':'拆分字符串并分别记录每个部分。
function makeProduct(key, val) {
var parts = key.split(':');
var attrs = {};
attrs.productId = parts[0];
attrs.quantityIterator = parts[1];
attrs.name = parts[2];
return { attributes: attrs, value: val};
}
使用示例:
makeProduct("46913872:2:Bust", 34);
返回对象:
{
attributes: {
name: "Bust",
productId: "46913872",
quantityIterator: "2"
},
value: 34
}
此answer中列出了按多个字段对对象进行排序的一般方法。
答案 4 :(得分:1)
这样的东西效果很好,你可以很容易地定义一个函数来包装它,并在给定比较属性的情况下对jQuery对象进行排序:
var $jobj = jQuery( '.jcss' ); // your selector here
var $jarr = [];
$jobj.each( function () {
$jarr.push( jQuery( this ) );
} );
$jarr.sort( function ( a, b ) {
var attr = {}; // your comparison attribute here
attr.a = parseInt( a.data( 'priority' ) || 0 );
attr.b = parseInt( b.data( 'priority' ) || 0 );
return attr.a < attr.b ? -1 : attr.a > attr.b ? 1 : 0;
} );
$jobj = jQuery( jQuery.map( $jarr, function ( obj, i ) {
return obj[0];
} ) );
// whatever you need to do here
$jobj.css( { 'text-decoration': 'blink' } );