Организовать дубликат объекта в массиве Javascript для получения одного значения - PullRequest
0 голосов
/ 06 марта 2019

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

var myValues = [
{
    client: "FIRE",
    firstname: "Test",
    id: "test@fire.com",
    arrangeid: "FIREFOX",
    region: "FOP",
    secondname: "Testy",
    status: "Approved"
},
{
    client: "FIRE",
    firstname: "Test",
    id: "test@fire.com",
    arrangeid: "BUZZZZZZ",
    region: "FOP",
    secondname: "Testy",
    status: "Approved"
},
{
    client: "PANTER",
    firstname: "Panty",
    id: "panty@panter.com",
    arrangeid: "PANTER",
    region: "PAN",
    secondname: "mc panty",
    status: "Approved"
},
{
    client: "BAT",
    firstname: "Bruce",
    id: "bat@bat.com",
    arrangeid: "BLACKBAT",
    region: "BLK",
    secondname: "Wyne",
    status: "Approved"
}

]

Итак, у меня есть этот объект, первые два идентификатора одинаковы, но они имеют разное расположение.Я хочу быть в состоянии присоединиться к ним, чтобы собрать их вместе.Где объект выглядит примерно так:

    var myValues = [
{
    client: "FIRE",
    firstname: "Test",
    id: "test@fire.com",
    arrangeid: ["BUZZZZZZ", "FIREFOX"],
    region: "FOP",
    secondname: "Testy",
    status: "Approved"
},
{
    client: "PANTER",
    firstname: "Panty",
    id: "panty@panter.com",
    arrangeid: ["PANTER"],
    region: "PAN",
    secondname: "mc panty",
    status: "Approved"
},
{
    client: "BAT",
    firstname: "Bruce",
    id: "bat@bat.com",
    arrangeid: ["BLACKBAT"],
    region: "BLK",
    secondname: "Wyne",
    status: "Approved"
}

]

У меня есть jsfidle здесь , где я вроде получаю результат.Можно ли сделать это лучше, чище.Правильно ли я подошел к нему?

Ответы [ 5 ]

1 голос
/ 06 марта 2019

Вы можете использовать reduce, Object.values() и синтаксис распространения следующим образом:

var myValues = [{client:"FIRE",firstname:"Test",id:"test@fire.com",arrangeid:"FIREFOX",region:"FOP",secondname:"Testy",status:"Approved"},{client:"FIRE",firstname:"Test",id:"test@fire.com",arrangeid:"BUZZZZZZ",region:"FOP",secondname:"Testy",status:"Approved"},{client:"PANTER",firstname:"Panty",id:"panty@panter.com",arrangeid:"PANTER",region:"PAN",secondname:"mc panty",status:"Approved"},{client:"BAT",firstname:"Bruce",id:"bat@bat.com",arrangeid:"BLACKBAT",region:"BLK",secondname:"Wyne",status:"Approved"}];

const merged = myValues.reduce((acc, a) => {
  acc[a.client] = acc[a.client] || { ...a, arrangeid: [] };
  acc[a.client].arrangeid.push(a.arrangeid);
  return acc;
},{})

const output = Object.values(merged);
console.log(output)

Аккумулятор - это объект с каждым уникальным client в качестве ключа, чтобы их было проще сгруппировать.

{
  "FIRE": {
    "client": "FIRE",
    "firstname": "Test",
    "id": "test@fire.com",
    "arrangeid": [ "FIREFOX", "BUZZZZZZ" ],
    "region": "FOP",
    "secondname": "Testy",
    "status": "Approved"
  },
  "PANTER": {
    "client": "PANTER",
    "id": "panty@panter.com",
    "arrangeid": [
      "PANTER"
    ],
   ...
  }
  ...
}
0 голосов
/ 07 марта 2019

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

const pick = (fields, obj) => fields.reduce((o, fld) => ({...o, [fld]: obj[fld]}), {})

const groupAndMerge = (groupFields, mergeFields, xs) => 
  Object.values(xs.reduce(
    (a, x, _, __, key = JSON.stringify(pick(groupFields, x))) => 
      (a[key] = (a[key] || []).concat(x)) && a,
    {}
  )).map(xs => ({
    ...xs[0],
    ...mergeFields.reduce((a, f) => ({...a, [f]: xs.map(x => x[f])}), {})
  }))

const myValues = [{arrangeid: "FIREFOX", client: "FIRE", firstname: "Test", fid: "test@fire.com", region: "FOP", secondname: "Testy", status: "Approved"}, {arrangeid: "BUZZZZZZ", client: "FIRE", firstname: "Test", fid: "test@fire.com", region: "FOP", secondname: "Testy", status: "Approved"}, {arrangeid: "PANTER", client: "PANTER", firstname: "Panty", fid: "panty@panter.com", region: "PAN", secondname: "mc panty", status: "Approved"}, {arrangeid: "BLACKBAT", client: "BAT", firstname: "Bruce", fid: "bat@bat.com", region: "BLK", secondname: "Wyne", status: "Approved"}]

const result = groupAndMerge(['client', 'id'], ['arrangeid'], myValues)

console.log(result)

Вспомогательная функция pick просто выбирает определенные свойства целевого объекта, так что pick(['a', 'c'], {a: 1, b: 2, c: 3}) //=> {a: 1, c: 3}.

groupAndMerge использует первый параметр (здесь ['client', 'id']), чтобы определить поля, которые должны быть одинаковыми, и второй (здесь ['arrangeid']), чтобы показать, какие из них должны быть сгруппированы.

Вы упоминаете, что первые два имеют одинаковые id. Мой код проверяет client и id; это как доказательство концепции, но это может быть полезно.

Есть одно предостережение по поводу использования этого: оно хорошо сливается только со строковыми или числовыми значениями. Некоторые другие могут работать, но я бы на это не рассчитывал. (Это также верно по крайней мере для одного другого ответа здесь, но я не знаю, важно ли это для вас.)

Преимущество, которое я вижу в этом, состоит в том, что это лишь немного сложнее, чем реализация на заказ, и это полезно в ряде других обстоятельств.

0 голосов
/ 06 марта 2019

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

function collectByField(data, key, prop) {
    const collection = new Map();
    for (const obj of data) {
         let item = collection.get(obj[key]);
         if (item) {
             // add this item's property to the array
             item[prop].push(obj[prop]);
         } else {
             // put a copy of our object into the Map
             // convert prop to an array with one initial item in it
             let copy = Object.assign({}, obj);
             copy[prop] = [obj[prop]];
             collection.set(obj[key], copy);
         }
    }
    // now use the Set to create final array output
    return Array.from(collection.values());
}

let myValues = [
{
    client: "FIRE",
    firstname: "Test",
    id: "test@fire.com",
    arrangeid: "FIREFOX",
    region: "FOP",
    secondname: "Testy",
    status: "Approved"
},
{
    client: "FIRE",
    firstname: "Test",
    id: "test@fire.com",
    arrangeid: "BUZZZZZZ",
    region: "FOP",
    secondname: "Testy",
    status: "Approved"
},
{
    client: "PANTER",
    firstname: "Panty",
    id: "panty@panter.com",
    arrangeid: "PANTER",
    region: "PAN",
    secondname: "mc panty",
    status: "Approved"
},
{
    client: "BAT",
    firstname: "Bruce",
    id: "bat@bat.com",
    arrangeid: "BLACKBAT",
    region: "BLK",
    secondname: "Wyne",
    status: "Approved"
}
];

console.log(collectByField(myValues, "id", "arrangeid"));
0 голосов
/ 06 марта 2019

Вы можете создать Карту для обозначения объектов по их идентификатору, а затем заполнить массивы arrangeid:

const myValues = [{client: "FIRE",firstname: "Test",id: "test@fire.com",arrangeid: "FIREFOX",region: "FOP",secondname: "Testy",status: "Approved"},{client: "FIRE",firstname: "Test",id: "test@fire.com",arrangeid: "BUZZZZZZ",region: "FOP",secondname: "Testy",status: "Approved"}, {client: "PANTER",firstname: "Panty",id: "panty@panter.com",arrangeid: "PANTER",region: "PAN",secondname: "mc panty",status: "Approved"},{client: "BAT",firstname: "Bruce",id: "bat@bat.com",arrangeid: "BLACKBAT",region: "BLK",secondname: "Wyne",status: "Approved"}];

const map = new Map(myValues.map(o => [o.id, {...o, arrangeid: []}]));
myValues.forEach(o => map.get(o.id).arrangeid.push(o.arrangeid));
const result = [...map.values()];

console.log(result);
0 голосов
/ 06 марта 2019

Вы можете использовать reduce()

var myValues = [
{
    client: "FIRE",
    firstname: "Test",
    id: "test@fire.com",
    arrangeid: "FIREFOX",
    region: "FOP",
    secondname: "Testy",
    status: "Approved"
},
{
    client: "FIRE",
    firstname: "Test",
    id: "test@fire.com",
    arrangeid: "BUZZZZZZ",
    region: "FOP",
    secondname: "Testy",
    status: "Approved"
},
{
    client: "PANTER",
    firstname: "Panty",
    id: "panty@panter.com",
    arrangeid: "PANTER",
    region: "PAN",
    secondname: "mc panty",
    status: "Approved"
},
{
    client: "BAT",
    firstname: "Bruce",
    id: "bat@bat.com",
    arrangeid: "BLACKBAT",
    region: "BLK",
    secondname: "Wyne",
    status: "Approved"
}

]



let res = JSON.parse(JSON.stringify(myValues)).reduce((ac,a) => {
  let ind = ac.findIndex(x => x.id === a.id);
  a.arrangeid = [a.arrangeid];
  ind === -1 ? ac.push(a) : ac[ind].arrangeid.push(...a.arrangeid);
  return ac;
},[])
console.log(res);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...