当条件和字段名称相同时,如何不允许items数组中的重复项?

时间:2016-11-14 18:37:07

标签: javascript jquery arrays object

我有这段HT​​ML代码:

<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_fielddata_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_fielddata_condition相同,即使他们共享同一性值,也只有一个是不同的。正确的输出应该是:

Object {["asset_locations_name","=",["1212341047","1212341048","1212369641", "1212369653"]]: 1}

data_values使用新值进行更新,data_fielddata_condition保持唯一。

在这种情况下,第二次+执行的条件是:

  • 如果data_fielddata_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的更新版本显示了该问题。

1 个答案:

答案 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