Оптимальный способ отфильтровать записи из массива объектов в зависимости от значения - PullRequest
0 голосов
/ 23 февраля 2020
[

 {status: "ABC", groupID: "Group 1"}
 {status: "PQR", groupID: "Group 1"}
 {status: "ABC", groupID: "Group 1"}
 {status: "ABC", groupID: "Group 1"}
 {status: "XYZ", groupID: "Group 1"}

 {status: "ABC", groupID: "Group 2"}
 {status: "ABC", groupID: "Group 2"}
 {status: "ABC", groupID: "Group 2"}

 {status: "ABC", groupID: "Group 3"}
 {status: "PQR", groupID: "Group 3"}

 {status: "XYZ", groupID: "Group 4"}
 {status: "LMN", groupID: "Group 4"}
 {status: "PQR", groupID: "Group 4"}

 {status: "ABC", groupID: "Group 5"}

]

Выше представлен массив объектов, каждый из которых имеет 2 ключа (статус и идентификатор группы). Как отфильтровать идентификаторы групп, которые имеют только статус AB C (группа 2 и группа 5 согласно вышеуказанному массиву).

Объекты сортируются в соответствии с их groupID

Это работает, но не выглядит как оптимальное решение, потому что я не могу опустить весь пакет groupID при обнаружении другого статуса (например, Group 4 has).

jQuery.each(arrObjs,function(k,v){
                var thisStatus = v['status'];
                var thisGroup  = v['groupID'];    
                var grpIndex   = allGroupID.indexOf(thisGroup);

                (grpIndex == -1 && allGroupID.push(thisGroup));

                if(!(thisStatus == 'ABC')){
                    allGroupID.splice(grpIndex, 1);
                }   
             });  

Необходимый результат:

['Group 2','Group 5'] //the Group ID's which have status ABC only, Group 1,3 & 4 dont qualify because they have other status values too.

Извините, если это просто вопрос, основанный на мнении.

Ответы [ 3 ]

1 голос
/ 23 февраля 2020

Вы можете выбрать один подход l oop и проверить прежнюю группу и взять переменную для хранения и массив группы.

Если группа меняется, отметьте keep и добавьте сгруппированные элементы к набору результатов.

var array = [{ status: "ABC", groupID: "Group 1" }, { status: "PQR", groupID: "Group 1" }, { status: "ABC", groupID: "Group 1" }, { status: "ABC", groupID: "Group 1" }, { status: "XYZ", groupID: "Group 1" }, { status: "ABC", groupID: "Group 2" }, { status: "ABC", groupID: "Group 2" }, { status: "ABC", groupID: "Group 2" }, { status: "ABC", groupID: "Group 3" }, { status: "PQR", groupID: "Group 3" }, { status: "XYZ", groupID: "Group 4" }, { status: "LMN", groupID: "Group 4" }, { status: "PQR", groupID: "Group 4" }, { status: "ABC", groupID: "Group 5" }],
    result = [],
    lastGroupID,
    group = [],
    keepGroup = false;

for (let item of array) {
    if (lastGroupID !== item.groupID) {
        if (keepGroup) result.push(group[0]);
        lastGroupID = item.groupID;
        group = [];
        keepGroup = true;
    }
    if (item.status !== 'ABC') keepGroup = false;
    group.push(item);
}
if (keepGroup) result.push(group[0]);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 голос
/ 23 февраля 2020

Вы могли бы использовать Установить и уменьшить . По сути, вы отслеживаете группу, которую хотите игнорировать, чтобы не добавлять их в окончательные результаты:

var arr = [
 {status: "ABC", groupID: "Group 1"},
 {status: "PQR", groupID: "Group 1"},
 {status: "ABC", groupID: "Group 1"},
 {status: "ABC", groupID: "Group 1"},
 {status: "XYZ", groupID: "Group 1"},

 {status: "ABC", groupID: "Group 2"},
 {status: "ABC", groupID: "Group 2"},
 {status: "ABC", groupID: "Group 2"},

 {status: "ABC", groupID: "Group 3"},
 {status: "PQR", groupID: "Group 3"},

 {status: "XYZ", groupID: "Group 4"},
 {status: "LMN", groupID: "Group 4"},
 {status: "PQR", groupID: "Group 4"},

 {status: "ABC", groupID: "Group 5"}
];

const filterByStatus = (st, array) => {
  const ignore = new Set();

  return array.reduce((acc, {status, groupID}) => {
    if (status !== st) {
      ignore.add(groupID);
      acc.delete(groupID);
    } else if (!ignore.has(groupID)) {
      acc.add(groupID);
    }
    return acc;    
  }, new Set())
}

filterByStatus("ABC", arr);
1 голос
/ 23 февраля 2020

Вы можете сначала сгруппировать их по статусу в один объект, а затем отфильтровать значения на основе желаемого состояния, используя методы filter и every.

const data = [{"status":"ABC","groupID":"Group 1"},{"status":"PQR","groupID":"Group 1"},{"status":"ABC","groupID":"Group 1"},{"status":"ABC","groupID":"Group 1"},{"status":"XYZ","groupID":"Group 1"},{"status":"ABC","groupID":"Group 2"},{"status":"ABC","groupID":"Group 2"},{"status":"ABC","groupID":"Group 2"},{"status":"ABC","groupID":"Group 3"},{"status":"PQR","groupID":"Group 3"},{"status":"XYZ","groupID":"Group 4"},{"status":"LMN","groupID":"Group 4"},{"status":"PQR","groupID":"Group 4"},{"status":"ABC","groupID":"Group 5"}]

const filterByStatus = (data, status) => {
  const grouped = data.reduce((r, e) => {
    if (!r[e.groupID]) r[e.groupID] = [e]
    else r[e.groupID].push(e)
    return r;
  }, {})

  return Object.values(grouped)
    .filter(a => a.every(e => e.status === status))
    .flat()
}

console.log(filterByStatus(data, 'ABC'))

Чтобы получить массив просто groupID, которые все соответствуют статусу, вы можете использовать другой подход с Set, чтобы получить все уникальные groupID, а затем использовать фильтр, чтобы получить только нужные .

const data = [{"status":"ABC","groupID":"Group 1"},{"status":"PQR","groupID":"Group 1"},{"status":"ABC","groupID":"Group 1"},{"status":"ABC","groupID":"Group 1"},{"status":"XYZ","groupID":"Group 1"},{"status":"ABC","groupID":"Group 2"},{"status":"ABC","groupID":"Group 2"},{"status":"ABC","groupID":"Group 2"},{"status":"ABC","groupID":"Group 3"},{"status":"PQR","groupID":"Group 3"},{"status":"XYZ","groupID":"Group 4"},{"status":"LMN","groupID":"Group 4"},{"status":"PQR","groupID":"Group 4"},{"status":"ABC","groupID":"Group 5"}]

const filterByStatus = (data, status) => {
  const groups = new Set(data.map(({groupID}) => groupID))
  return [...groups].filter(g => !data.some(e => e.groupID == g && e.status !== status ))
}

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