如果某些“熟悉”,则返回错误;对象内的字段不相邻

Return error if some "familiar" fields within an object are not adjacent

本文关键字:对象 字段 错误 返回 熟悉 如果      更新时间:2023-09-26

我有一个对象,如:

var dataObj = {
'hre': {groupID: 1},
'bla': {groupID: 1},
3: {groupID: 0},
4: {groupID: 2},
16: {groupID: 2},
6: {groupID: 2},
7: {groupID: 0},
64893: {groupID: 0},
9: {groupID: 1}
}

当group为0时,表示该字段不属于任何group

同一组中的字段必须相邻。否则会抛出一个错误。

因此,例如上面的对象会抛出一个错误,因为组1的字段不相邻。

寻找一种有效的方法来完成这件事(或者任何方法,因为我已经找了一段时间了)。

var error = false;
var previousGroupID = null;
var thisGroupID = null;
var previousFieldGroupID = null;
for (index in dataArray) {
    if (dataObj[index]['groupID'] > 0) {
        thisGroupID = dataObj[index]['groupID'];
        if (previousFieldGroupID == 0 && thisGroupID ==  previousGroupID) {
            error = true;
        }
    }
    previousFieldGroupID = dataObj[index]['groupID'];
}
操纵http://jsfiddle.net/zq2w7w9t/1/

假设您的JavaScript引擎保留了成员的排序(大多数都保留了,但是它们不必,参见这个问题):

function hasError(dataObj) {
  var error = false;
  var previousGroupID = -1;
  var thisGroupID = -1;
  var seenGroups = new Set();
  for (index in dataArray) {
    thisGroupID = dataObj[index].groupID;
    if (previousGroupID !== thisGroupID) {
      if (seenGroups.has(thisGroupID)) {
        if (thisGroupID !== 0) error = true;
      } else {
        seenGroups.add(thisGroupID);
      }
    }
    previousGroupID = thisGroupID;
  }
  return error;
}

否则,您可以使用Map,它保证保留条目顺序:

function hasError(dataMap) {
  var error = false;
  var previousGroupID = -1;
  var thisGroupID = -1;
  var seenGroups = new Set();
  var thisGroup = null;
  for (thisGroup of dataMap.values()) {
    thisGroupID = thisGroup.groupID;
    if (previousGroupID !== thisGroupID) {
      if (seenGroups.has(thisGroupID)) {
        if (thisGroupID !== 0) error = true;
      } else {
        seenGroups.add(thisGroupID);
      }
    }
    previousGroupID = thisGroupID;
  }
  return error;
}
var m = new Map();
m.set('hre', { groupID: 1 });
m.set('bla', { groupID: 1 });
m.set(3, { groupID: 0 });
m.set(4, { groupID: 2 });
m.set(5, { groupID: 0 });
m.set(1, { groupID: 1 });
console.log(hasError(m));

或者您可以将其分解为单独的函数:

function listHasError(list) {
  var error = false;
  var previousGroupID = -1;
  var thisGroupID = -1;
  var seenGroups = new Set();
  var thisGroup = null;
  list.forEach(function(thisGroupID) {
    if (previousGroupID !== thisGroupID) {
      if (seenGroups.has(thisGroupID)) {
        if (thisGroupID !== 0) error = true;
      } else {
        seenGroups.add(thisGroupID);
      }
    }
    previousGroupID = thisGroupID;
  });
  return error;
}
function extractGroupsFromMap(dataMap) {
  var res = [];
  for (thisGroup of dataMap.values()) {
    res.push(thisGroup.groupID);
  }
  return res;
}
function extractGroupsFromObj(dataObj) {
  var res = [];
  for (index in dataObj) {
    res.push(dataObj[index].groupID);
  }
  return res;
}
var dataObj = {
  'hre': {groupID: 1},
  'bla': {groupID: 1},
  3: {groupID: 0},
  4: {groupID: 2},
  16: {groupID: 2},
  6: {groupID: 2},
  7: {groupID: 0},
  64893: {groupID: 0},
  9: {groupID: 1}
};
console.log(listHasError(extractGroupsFromObj(dataObj)));

好的,假设:

  • 你的对象有任意键
  • 每个值有一个数值索引属性和一个groupId
  • 非连续元素的组0不是错误
  • 索引属性互斥且连续

假设你的对象是这样的:

var    yourObject = {
    'a1': {     index: 1,       groupId: 1  },
    'b2': {     index: 2,       groupId: 1  },
    'c3': {     index: 3,       groupId: 0  },
    'd4': {     index: 4,       groupId: 5  },
    'e5': {     index: 5,       groupId: 5  },
    'g6': {     index: 6,       groupId: 5  },
    'h7': {     index: 7,       groupId: 'A'},
    'i8': {     index: 8,       groupId: 0  },
    'j9': {     index: 9,       groupId: 'A'}
    };

(请注意,我有意使用非连续的,也不是唯一的数字组id)。

然后我将你的对象分组使用:

var groups={};
Object.keys(yourObject)
    .forEach(function (key) {
        var thevalue = yourObject[key],
            groupId = thevalue.groupId;
        groups[groupId] = groups[groupId] || [];
        groups[groupId].push(thevalue.index);
});

此时,groups是一个键为0、1、5和'A'的对象,它们的值是index属性的值(我们说过是连续的和排他的)。

{
    0: [3,8],
    1: [1,2],
    5: [4,5,6],
    'A':[7,9]
}

我将迭代groups,对于每个组,如果它有单个元素或它是组0,我将跳过验证。

如果它有多于1个元素,并且它不是组0,那么我将对它的元素排序并迭代它们。由于索引是连续的,因此这些排序数组中的每一个都不能有差值> 1的项

var hasError = false;
Object.keys(groups).forEach(function (groupId) {
    if (groupId !== 0 && groups[groupId] && groups[groupId].length > 1) {
        var sortedElements = groups[groupId].sort(function (a, b) {
            return a > b;
        });
        console.log('Group ' + groupId, sortedElements);
        for (var index = 1; index < sortedElements.length; index++) {
            if ((sortedElements[index] - sortedElements[index - 1]) > 1) {
                hasError = true;
                console.warn('Error detected');
            }
        }
    }
});