Добавить ключ к набору объектов в наборе массива при условии соответствия ключа объекта - PullRequest
0 голосов
/ 04 июля 2019

У меня есть проблема, которую я пытался решить безрезультатно.

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

Например, два объекта в массивах data[0][0] и data[0][1] совместно используют ключ color white и black, то есть match: true для всех объектов в data[0][0] и data[0][1], но не data[0][2], поскольку у него есть только один, поэтому будет match: false.

Результат будет выглядеть следующим образом:

data = [
  [{
    name: 'car',
    color: 'black',
    group: 0,
    match: true
  },{
    name: 'car',
    color: 'white',
    group: 0,
    match: true
  },{
    name: 'car',
    color: 'blue',
    group: 0,
    match: true
  }],
  [{
    name: 'truck',
    color: 'black'
    group: 1,
    match: true
  },{
    name: 'truck',
    color: 'white',
    group: 1,
    match: true
  },{
    name: 'truck',
    color: 'yellow',
    group: 1,
    match: true
  }],
  [{
    name: 'moto',
    color: 'black',
    group: 2,
    match: false
  },{
    name: 'moto',
    color: 'pink',
    group: 2,
    match: false
  },{
    name: 'moto',
    color: 'orange',
    group: 2,
    match: false
  }]
]

Это небольшой пример.Фактические данные имеют сотни массивов, и совпадение должно быть не менее 7

Ответы [ 2 ]

1 голос
/ 04 июля 2019

Вы можете рассчитать пересечение colors в виде массива и сравнить length с ожидаемым порогом, чтобы определить значение match в своих результатах.

function match (data, key, filter, transform) {
  const arrays = data.map(
    array => array.map(key)
  );
  const groups = arrays.map(
    array => ({ array, set: new Set(array) })
  );
  const matches = groups.map(
    outer => groups.some(
      inner => (
        outer !== inner &&
        filter(outer.array.filter(inner.set.has, inner.set))
      )
    )
  );

  return data.map(
    (array, index) => transform(array, matches[index])
  );
}

const data = [[{name:'car',color:'black',group:0},{name:'car',color:'white',group:0},{name:'car',color:'blue',group:0}],[{name:'truck',color:'black',group:1},{name:'truck',color:'white',group:1},{name:'truck',color:'yellow',group:1}],[{name:'moto',color:'black',group:2},{name:'moto',color:'pink',group:2},{name:'moto',color:'orange',group:2}]];

const result = match(
  data,
  value => value.color,
  keys => keys.length >= 2,
  (array, match) => array.map(
    value => Object.assign(value, { match })
  )
);

console.log(result);

Это создает Set() для каждого массива colors для более эффективного расчета пересечения на каждом проходе без пропуска дубликатов, если они есть.

Для ваших фактических данных вы можете изменить параметр filter на

colors => colors.length >= 7
0 голосов
/ 04 июля 2019

Вы можете считать черный и белый и получать новые объекты с помощью match.

var data = [[{ name: 'car', color: 'black', group: 0 }, { name: 'car', color: 'white', group: 0 }, { name: 'car', color: 'blue', group: 0 }], [{ name: 'truck', color: 'black', group: 1 }, { name: 'truck', color: 'white', group: 1 }, { name: 'truck', color: 'yellow', group: 1 }], [{ name: 'moto', color: 'black', group: 2 }, { name: 'moto', color: 'pink', group: 2 }, { name: 'moto', color: 'orange', group: 2 }]],
    result = data.map(a => {
        var count = {},
            match = a.some(({ color }) => {
                count[color] = (count[color] || 0) + 1;
                return count.black === 1 && count.white === 1;
            });
        return a.map(o => Object.assign({}, o, { match }));
    });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...