我有这段HTML代码:
<select id="table" name="table">
<option></option>
<option value="asset_locations">Asset Locations</option>
<option value="companies">Company</option>
</select>
<select id="fields" name="fields">
<option></option>
<option value="asset_locations_id">asset_locations_id</option>
<option value="companies_id">companies_id</option>
<option value="region_id">region_id</option>
<option value="asset_locations_name">asset_locations_name</option>
...
</select>
<select id="conditions">
<option></option>
<option value="=">Equal to</option>
<option value="<>">Not Equal to</option>
<option value=">">Greater Than (Strictly)</option>
...
</select>
<select id="condition_value_1" multiple="multiple" style="display: none">
<option></option>
</select>
<button id="add" style="display: none">Add</button>
我正在构建一个对象如下:
$(function() {
...
var list = {};
var items = [];
...
$('#add').click(function() {
var data_field = $('#fields :selected').val();
var data_condition = $('#conditions :selected').val();
var data_values = $('#condition_value_1').val();
var item = [
data_field,
data_condition,
data_values
];
var key = JSON.stringify(item);
if (list[key] === 1) return; // skip
list[key] = 1;
items.push(item);
console.log(list);
console.log(items);
});
});
它有效,但它允许data_field
和data_condition
的重复,这意味着它们应该是唯一的,并且只更新它data_values
。例如,如果您执行上面的代码并为给定条件添加一些值,您应该在控制台上以下列结尾:
Object {["asset_locations_name","=",["1212341047","1212341048","1212369641"]]: 1}
现在,如果您再次运行它并更改data_values
,您将在控制台处以下列结尾:
Object {["asset_locations_name","=",["1212341047","1212341048","1212369641"]]: 1, ["asset_locations_name","=",["1212341047","1212341048","1212369653"]]: 1}
正如您注意到data_field
和data_condition
相同,即使他们共享同一性值,也只有一个是不同的。正确的输出应该是:
Object {["asset_locations_name","=",["1212341047","1212341048","1212369641", "1212369653"]]: 1}
data_values
使用新值进行更新,data_field
和data_condition
保持唯一。
在这种情况下,第二次+执行的条件是:
data_field
和data_condition
保持不变,则查找其值并正确更新,不得重复。以上是另一个例子:
1st exec:
input: asset_locations_name, in, ["1212341047","1212341048","1212369641"]
output: Object {["asset_locations_name","=",["1212341047","1212341048","1212369641"]]: 1}
2nd exec:
input: asset_locations_name, in, ["1212341047","1212341048","1212369653"]
output: Object {["asset_locations_name","=",["1212341047","1212341048","1212369641", "1212369653"]]: 1}
3rd exec:
input: asset_locations_name, not in, ["1212341047","1212341048","1212369653"]
output: Object {["asset_locations_name","=",["1212341047","1212341048","1212369641"]]: 1, ["asset_locations_name","<>",["1212341047","1212341048","1212369653"]]: 1}
请注意2nd
exec中我如何保留相同的条目,但更新它data_values
这是正确的行为。
注意3rd
exec中我们如何更改data_condition
的值,使其成为新条目,无论data_values
是否相同。如果有任何拼写错误,我不知道或你不明白任何事情让我知道,我会尽力让这一点清楚。
注意:该解决方案应与旧版浏览器兼容。 (我们正在更新,但在此之前我需要使用旧的浏览器兼容性)
我留下了一个工作小提琴here。
我怎样才能做到这一点?有什么帮助吗?
更新:如果按键保持
,则不会累积值目前解决方案存在一个问题,即当密钥保持不变时值不会累积。
小提琴here的更新版本显示了该问题。
答案 0 :(得分:2)
这是使用ES6 Map
的理想情况。但是,当你要求向后兼容性时,我会建议:
var items = {};
//...
var key = JSON.stringify([data_field, data_condition]); // only these two!
items[key] = item; // will overwrite if same key
// if you need to have it as an array:
for (key in items) {
console.log(items[key]);
}
// ...
您更新的fiddle。如果您需要将此items
对象转换为普通数组,我还会包含一个函数。
为了累积为同一个键选择的值,您可以使用此代码更新items[key]
:
if (typeof data_values === 'string') {
items[key] = data_values; // no accumulation for simple values
} else {
items[key] = items[key] || [];
// make values cumulative, while avoiding duplicates:
for (var i = 0; i < data_values.length; i++) {
if (items[key].indexOf(data_values[i]) == -1)
items[key].push(data_values[i]);
}
}
这改变了一点结构,因为现在只有data_values
被存储为值,所以toArray
函数需要从密钥中取出其余部分:
function toArray(items) {
result = [];
for (key in items) {
// decode key, and concatenate the values array to it
result.push(JSON.parse(key).concat([items[key]]));
}
return result;
}
更新了fiddle