Как сохранить объекты с указанным уникальным атрибутом c в массиве в javascript? - PullRequest
1 голос
/ 04 мая 2020

У меня есть такой массив:

var myarray = [
    {"scaleId":"001","currentWeight":0.200}
    {"scaleId":"002","currentWeight":0.300},
    {"scaleId":"001","currentWeight":0.255},
    {"scaleId":"002","currentWeight":0.000},
    {"scaleId":"003","currentWeight":0.340},
    ]

, и я хочу сохранить объекты, которые имеют уникальный scaleId. Итак, для приведенного выше примера, вывод будет выглядеть так (любой случайный объект может быть сохранен, если scaleId является дубликатом):

myarray = [
    {"scaleId":"001","currentWeight":0.200}
    {"scaleId":"002","currentWeight":0.300},
    {"scaleId":"003","currentWeight":0.340},
    ]

Я уже использую библиотеку подчеркивания в своем приложении, так что я в порядке с использованием подчеркивания. Я придумал решение, но оно не работает, как ожидалось. Так что любая помощь будет отличной.

Ответы [ 4 ]

1 голос
/ 04 мая 2020

Map с и Set с часто являются подходящими структурами для поддержания уникальности. Вот простая функция, которая использует Map для поддержки единственного уникального значения, заданного именем свойства:

const uniqByProp = (prop) => (xs) =>
  [... new Map (xs .map ((x) => [x [prop], x])) .values ()]

var myarray = [{scaleId: "001", currentWeight: 0.200}, {scaleId: "002", currentWeight: 0.300}, {scaleId: "001", currentWeight: 0.255}, {scaleId: "002", currentWeight: 0.000}, {scaleId: "003", currentWeight: 0.340}]

console .log (
  uniqByProp ('scaleId') (myarray)
)
.as-console-wrapper {min-height: 100% !important; top: 0}

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

0 голосов
/ 04 мая 2020

Вы также можете использовать Array.prototype.reduceRight() для упрощения агрегации логи c:

let myarray = [
  { scaleId: '001', currentWeight: 0.2 },
  { scaleId: '002', currentWeight: 0.3 },
  { scaleId: '001', currentWeight: 0.255 },
  { scaleId: '002', currentWeight: 0 },
  { scaleId: '003', currentWeight: 0.34 }
];

myarray = Object.values(
  myarray.reduceRight(
    (acc, cur) => (acc[cur.scaleId] = cur, acc),
    {}
  )
).reverse(); // optional if order of output matters to you

console.log(myarray);

или построить Map из пар ключ-значение, сгенерированных с использованием Array.prototype.map():

let myarray = [
  { scaleId: '001', currentWeight: 0.2 },
  { scaleId: '002', currentWeight: 0.3 },
  { scaleId: '001', currentWeight: 0.255 },
  { scaleId: '002', currentWeight: 0 },
  { scaleId: '003', currentWeight: 0.34 }
];

myarray = Array.from(
  new Map(
    myarray.map(
      val => [val.scaleId, val]
    ).reverse()
  ).values()
).reverse(); // optional if order of output matters to you

console.log(myarray);

Мы используем Array.prototype.reverse() в массиве, передаваемом конструктору, чтобы гарантировать, что порядок вставки позволяет более ранним значениям иметь приоритет над более поздними значениями.

0 голосов
/ 04 мая 2020

Вы можете сделать это таким образом (если вы используете ES6 / ES2015 или более позднюю версию), используя Set для фильтрации уникальных scaleIds в первую очередь и передавая новый массив с помощью метода Array.find

var myarray = [
    {"scaleId":"001","currentWeight":0.200},
    {"scaleId":"002","currentWeight":0.300},
    {"scaleId":"001","currentWeight":0.255},
    {"scaleId":"002","currentWeight":0.000},
    {"scaleId":"003","currentWeight":0.340},
]

let scaleIds = [...new Set(myarray.map(item => item.scaleId))];
let filtered = []
scaleIds.forEach(scaleId => filtered.push(myarray.find(item => item.scaleId === scaleId)))

console.log(filtered)
0 голосов
/ 04 мая 2020

Используйте reduce и внутри обратного вызова проверьте, есть ли в объекте аккумулятора ключ с таким же scaleId. Если так, то добавьте значение к этому ключу. Наконец, используйте Object.values для создания массива значений

var myarray = [{
    "scaleId": "001",
    "currentWeight": 0.200
  },
  {
    "scaleId": "002",
    "currentWeight": 0.300
  },
  {
    "scaleId": "001",
    "currentWeight": 0.255
  },
  {
    "scaleId": "002",
    "currentWeight": 0.000
  },
  {
    "scaleId": "003",
    "currentWeight": 0.340
  }
]

let data = myarray.reduce((acc, curr) => {
  if (!acc[curr.scaleId]) {
    acc[curr.scaleId] = curr
  }
  return acc;
}, {});

console.log(Object.values(data))
...