Найти в массиве объектов двойные заданные значения - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть пользовательский интерфейс, в котором есть таблица HTML, в которую мы можем добавлять динамические строки и столбцы (angularjs)

Таблица имеет 2 статических столбца ID & Description, остальные столбцы являются динамическими столбцами, где пользователь должендобавить один или несколько столбцов. (щелчок по кнопке). Один щелчок по кнопке «Сохранить». Я хочу проверить, добавил ли пользователь уникальные динамические столбцы или нет.

Ниже переменной хранится массив строк, как показано ниже:

 $scope.myTable.Rows 

Ниже приведен массив, сгенерированный, когда пользователь добавляет только один динамический столбец и 2 строки.Здесь id & description - статический столбец, а "0" - добавленный динамический столбец.

{0: "1111", description: "desc1", id: "1111"}
{0: "2222", description: "desc2", id: "2222"}

Другой пример добавления 3 динамических столбцов и 3 строк:

{0: "a1", 1: "a2", 2: "a3", description: "desc1", id: "1111"}
{0: "a5", 1: "a6", 2: "a7", description: "desc2", id: "2222"}
{0: "a9", 1: "a10", 2: "a11", description: "desc3", id: "3333"}

Я хочупроверить, является ли указанный массив уникальным только с помощью комбинации динамических столбцов.т.е. согласно указанному выше массиву установленные значения динамических столбцов 0,1,2 не должны повторяться ни в одной другой строке массива.

Таким образом, приведенный ниже массив не должен проходить проверку:

{0: "a1", 1: "a2", 2: "a3", description: "desc1", id: "1111"}
{0: "a5", 1: "a6", 2: "a7", description: "desc2", id: "2222"}
{0: "a1", 1: "a2", 2: "a3", description: "desc3", id: "3333"}

Как вы видите, 3-й ряд выше похож на 1-й ряд.Я не хочу принимать во внимание столбец "id" & "description"

Хотя ниже все еще уникален:

{0: "a1", 1: "a2", 2: "a3", description: "desc1", id: "1111"}
{0: "a5", 1: "a6", 2: "a7", description: "desc2", id: "2222"}
{0: "a1", 1: "a2", 2: "a9", description: "desc3", id: "3333"}

Я попытался просмотреть пару постов здесь: Как я могу проверить, есть ли в массиве объектов повторяющиеся значения свойств?

Но большинство из них приходится на просмотр одного свойства и посмотреть, есть ли дубликаты, но не в объединенном наборе.

Я надеюсь, что дал четкое объяснение моего требования.Дайте мне знать, если вам нужна дополнительная информация.

- Обновлено -

Я пробовал как:

 let array = [
  {0: "a1", 1: "a2", 2: "a3", description: "desc1", id: "1111"},
 {0: "a5", 1: "a6", 2: "a7", description: "desc2", id: "2222"},
 {0: "a1", 1: "a2", 2: "a3", description: "desc3", id: "3333"}];

 let jsonRows = JSON.parse(JSON.stringify(array));
 var valueArr = jsonRows.map(function(item){ return item."0" });
   //above gives error: Uncaught SyntaxError: Unexpected string
 var isDuplicate = valueArr.some(function(item, idx){ 
return valueArr.indexOf(item) != idx 
 });

console.log(jsonRows);

Ответы [ 3 ]

0 голосов
/ 11 сентября 2018

Это то, что я думаю, что мы можем сделать здесь очень просто, создать карту с ключом в качестве значения каждого динамического свойства каждой строки. Возьмите каждую строку и добавьте к карте, если свойство уже существует, найден повторяющийся элемент.

Я объединил каждое значение, чтобы создать уникальный ключ, используя || в качестве разделителя, используйте уникальный, который не будет значением для динамического свойства.

 function isUniqueData(data) {
    let map = {}, isUnique = true;
    data.filter(function(item, index) {
      let prop = "";
      for(var key in item) {
        if(key != "description" && key != "id") {
          prop += item[key] + "||";
        }  
      }
      if(map[prop]) {
        isUnique = false;
      } else {
        map[prop] = item;
      }
    }); 
    return isUnique;
 }

var data1 = [
  {0: "a1", 1: "a2", 2: "a3", description: "desc1", id: "1111"},
  {0: "a5", 1: "a6", 2: "a7", description: "desc2", id: "2222"},
  {0: "a5", 1: "a6", 2: "a7", description: "desc2", id: "2222"},
  {0: "a1", 1: "a2", 2: "a9", description: "desc3", id: "3333"}
];
console.log(isUniqueData(data1))

var data2 = [
  {0: "a1", 1: "a2", description: "desc1", id: "1111"},
  {0: "a5", 1: "a6", description: "desc2", id: "2222"},
  {0: "a1", 1: "a4", description: "desc3", id: "3333"}
];
console.log(isUniqueData(data2))
0 голосов
/ 11 сентября 2018

Перефразируя ваш вопрос:

При наличии нескольких ключей, как найти все строки в массиве, где пара ключ: значение встречается более одного раза?

Я использовал эти строки:

var rows = [
  {0: 'a1', 1: 'a2', 2: 'a3', description: 'desc1', id: '1111'},
  {0: 'a5', 1: 'a6', 2: 'a7', description: 'desc2', id: '2222'},
  {0: 'a1', 1: 'a2', 2: 'a3', description: 'desc3', id: '3333'}
];

Мой ответ, вероятно, немного многословен:

  1. Рекурсивно обойти массив по отдельному списку ключей, которые я хочу быть уникальными.
  2. Для каждого заданного ключа найдите количество вхождений каждого значения для этого ключа.
  3. Если счетчик для значения равен > 1, поместите строку в массив дубликатов

Вы можете сократить решение, используя такие функции, как # countBy в Lodash.

function duplicates(arr, keys = []) {
  if (keys.length) {
    const key = keys[0];
    const keyValueCounts = count(arr.map(row => row[key]));

    return duplicates(
      arr.reduce((acc, row) => {
        if (keyValueCounts[row[key]] > 1) {
          return acc.concat(row);
        } else {
          return acc;
        }
      }, []),
      keys.slice(1)
    );
  } else {
    return arr;
  }
}

/// or _.countsBy(arr);
function count(arr) {
  const counts = {};

  arr.forEach(value => {
    counts[value] = Number.isInteger(counts[value])
      ? counts[value] + 1
      : 1;
  });

  return counts;
}

console.log(duplicates(rows, [0, 1, 2]));
0 голосов
/ 11 сентября 2018

Вы можете написать функцию, которая просматривает все элементы, пока не найдет два элемента с одинаковыми свойствами 0, 1 и 2:

let testData = [{0: "a1", 1: "a2", 2: "a3", description: "desc1", id: "1111"},{0: "a5", 1: "a6", 2: "a7", description: "desc2", id: "2222"},{0: "a1", 1: "a2", 2: "a3", description: "desc3", id: "3333"}]


function areElementsUnique(arr) {
  if (arr.length === 1) return true; // no need to check if there is only one element
  for (el of arr) {
    if (arr.filter(elm => (el[0] === elm[0] && el[1] === elm[1] && el[2] === elm[2])).length > 1)
      return false
  };
  return true;
}

console.log(areElementsUnique(testData));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...