Как объединить / вставить itens в мой массив после группировки моего массива? - PullRequest
0 голосов
/ 20 марта 2019

Я получаю массив response с повторяющимися значениями.Id, Name и Cod, но есть и другие различия, такие как Indicator.Поэтому я сгруппировал свой массив с помощью метода Reduce.Это мой массив:

let myArray = [  
  {  
    "id":1,
    "name":"NAME1",
    "cod":"00CC",
    "indicator":{  
      "idIndicator":2,      
      "name":"MY-SECOND-NAME",
    }
  },
  {  
    "id":1,
    "name":"NAME1",
    "cod":"00CC",
    "indicator":{  
      "idIndicator":3,
      "name":"MY-FIST-NAME",
    }
  },
  {  
    "id":5,
    "name":"DWWW",
    "cod":"200CC",
    "indicator":{  
      "idIndicator":2,
      "name":"MY-SECOND-NAME",
    }
  },
  {  
    "id":5,
    "name":"DWWW",
    "cod":"200CC",
    "indicator":{  
      "idIndicator":3,
      "name":"MY-FIST-NAME",
    }
  }
]

console.log("My Array with duplicate values:" )
console.log(myArray)

    var group_to_values = myArray.reduce(function (obj, item) {
      obj[item.cod] = obj[item.cod] || [];
      obj[item.cod].push(item.indicator);
      return obj;
    }, {});

    var groups = Object.keys(group_to_values).map(function (key) {
      return {
        cod: key,
        indicatorItem: group_to_values[key]
      };
    });

console.log("My Array grouped:" )
console.log(groups)

Однако, поскольку reduce использует только 1 элемент (key), я теряю другие значения как: Id, Name

Поэтому я попытался использовать .map() и .filter() для поиска таких элементов, как id и name, используя cod в качестве ссылки, но я не добился большого успеха.Я куда-то иду, но не знаю, где: /

Поскольку я сравниваю элемент за элементом, конец моего возврата всегда будет последним элементом (cod) в моем массиве.Я понимаю, что поэтому возврат составляет всего cod 00CC

Это мой код:

let returnedItens = null

myArray.map(itemArray => {
  returnedItens = groups.filter(itemGroup => {
      if (itemArray.cod == itemGroup.cod) {
        return {
          id: itemArray.id,
          name: itemArray.name,
          cod: itemGroup.cod,
          indicator: itemGroup.indicator,
        }
      }
    })
  })

Итак, я хотел бы получить этот возврат с моим кодом выше:

[  
  {  
    "id":1,
    "name":"NAME1",
    "cod":"00CC",
    "indicator":[  
      {  
        "idIndicator":2,
        "name":"MY-SECOND-NAME",
      },
      {  
        "idIndicator":3,
        "name":"MY-FIST-NAME",
      }
    ]
  },
  {  
    "id":5,
    "name":"DWWW",
    "cod":"200CC",
    "indicator":[  
      {  
        "idIndicator":2,
        "name":"MY-SECOND-NAME",
      },
      {  
        "idIndicator":3,
        "name":"MY-FIST-NAME",
      }
    ]
  }
]

Пожалуйста, кто-нибудь может мне помочь?Как я могу это сделать?

Ответы [ 4 ]

2 голосов
/ 20 марта 2019

Вы можете использовать объект с ключами, представляющими данные, на которые вы хотите сократить, а именно, свойство .cod.После группировки используйте Object.values(), чтобы преобразовать ваши объекты обратно в массив.Временная сложность линейна.

let myArray = [ { "id":1, "name":"NAME1", "cod":"00CC", "indicator":{ "idIndicator":2, "name":"MY-SECOND-NAME", } }, { "id":1, "name":"NAME1", "cod":"00CC", "indicator":{ "idIndicator":3, "name":"MY-FIST-NAME", } }, { "id":5, "name":"DWWW", "cod":"200CC", "indicator":{ "idIndicator":2, "name":"MY-SECOND-NAME", } }, { "id":5, "name":"DWWW", "cod":"200CC", "indicator":{ "idIndicator":3, "name":"MY-FIST-NAME", } } ];
const result = {};

for (const o of myArray) {
  if (!(o.cod in result)) {
    result[o.cod] = o;
    result[o.cod].indicator = [o.indicator];
  }
  else {
    result[o.cod].indicator.push(o.indicator);
  }
}

console.log(Object.values(result));
1 голос
/ 20 марта 2019

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

let myArray = [  
  {  
    "id":1,
    "name":"NAME1",
    "cod":"00CC",
    "indicator":{  
      "idIndicator":2,      
      "name":"MY-SECOND-NAME",
    }
  },
  {  
    "id":1,
    "name":"NAME1",
    "cod":"00CC",
    "indicator":{  
      "idIndicator":3,
      "name":"MY-FIST-NAME",
    }
  },
  {  
    "id":5,
    "name":"DWWW",
    "cod":"200CC",
    "indicator":{  
      "idIndicator":2,
      "name":"MY-SECOND-NAME",
    }
  },
  {  
    "id":5,
    "name":"DWWW",
    "cod":"200CC",
    "indicator":{  
      "idIndicator":3,
      "name":"MY-FIST-NAME",
    }
  }
]
const copyMyArray = [...myArray];

myArray.forEach((arr, i) => {
  copyMyArray.forEach((ar, index) => {
    let same = arr.id === ar.id && arr.name === ar.name && arr.cod === ar.cod;
    if(same && index !== i) {
      arr.indicator = [ arr.indicator, ar.indicator];
      // do not loop next time
      copyMyArray.splice(index, 1);
      // remove from first array 
      myArray.splice(index, 1)
    }

  })
})
console.log(myArray)
1 голос
/ 20 марта 2019

Array.prototype.reduce - это правильный способ делать то, что вы хотите.

Array.prototype.filter и Array.prototype.map служат разным целям. Кроме того, вы неправильно используете их в своем фрагменте кода. (Пожалуйста, ознакомьтесь с ссылками на документы)

.map для преобразования каждого значения массива.

.filter - для извлечения определенных значений массива.

.reduce - возвращать один выход, получая доступ к каждому значению массива.

Ниже приведен рабочий код и пояснение:

let myArray = [  
  {  
    "id":1,
    "name":"NAME1",
    "cod":"00CC",
    "indicator":{  
      "idIndicator":2,      
      "name":"MY-SECOND-NAME",
    }
  },
  {  
    "id":1,
    "name":"NAME1",
    "cod":"00CC",
    "indicator":{  
      "idIndicator":3,
      "name":"MY-FIST-NAME",
    }
  },
  {  
    "id":5,
    "name":"DWWW",
    "cod":"200CC",
    "indicator":{  
      "idIndicator":2,
      "name":"MY-SECOND-NAME",
    }
  },
  {  
    "id":5,
    "name":"DWWW",
    "cod":"200CC",
    "indicator":{  
      "idIndicator":3,
      "name":"MY-FIST-NAME",
    }
  }
]

// If you don't understand what are `acc` and `curr`, read the doc I referenced above
const ret = myArray.reduce((acc, curr) => {

  // Get the index of the obj with same id, name and cod
  const indexOfSameObj = acc.findIndex(obj => {
    return obj.id === curr.id
        && obj.name === curr.name
        && obj.cod === curr.cod
  });
  
  if (indexOfSameObj >= 0){
    // If same obj exists, push next.indicator to the same obj
    acc[indexOfSameObj].indicator.push(curr.indicator);
  } else {
    // If same obj doesn't exist, push new obj with new structure to reduced array
    acc.push({
      id: curr.id,
      name: curr.name,
      cod: curr.cod,
      indicator: [curr.indicator]  // Make `.indicator` an array
    });
  }

  // Return the new reduced array
  return acc;

}, []  /* This empty array is the initial value of reduced array */);

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

Кредиты Ггорлену за введение Object.values метода.Чтобы получить более элегантное и быстрое решение, вы можете использовать метод Reduce с моим следующим кодом:

let myArray = [  
  {  
    "id":1,
    "name":"NAME1",
    "cod":"00CC",
    "indicator":{  
      "idIndicator":2,      
      "name":"MY-SECOND-NAME",
    }
  },
  {  
    "id":1,
    "name":"NAME1",
    "cod":"00CC",
    "indicator":{  
      "idIndicator":3,
      "name":"MY-FIST-NAME",
    }
  },
  {  
    "id":5,
    "name":"DWWW",
    "cod":"200CC",
    "indicator":{  
      "idIndicator":2,
      "name":"MY-SECOND-NAME",
    }
  },
  {  
    "id":5,
    "name":"DWWW",
    "cod":"200CC",
    "indicator":{  
      "idIndicator":3,
      "name":"MY-FIST-NAME",
    }
  }
]

let newArray = myArray.reduce(function(prev,next){

    let key = next.cod;
    if (!prev[key]){
       prev[key] = next;
       prev[key]["indicator"]=[prev[key]["indicator"]]
    } else {
       prev[key]["indicator"].push(next["indicator"])
    }
    return prev
},[])

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