Уникальный ключ с ненулевыми значениями - PullRequest
3 голосов
/ 27 января 2020

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

const es = [
  ['A', 'A1'], // first A key
  ['B', null],
  ['C', null],
  ['A', null], // second A key
  ['B', null],
  ['C', null],
  ['D', 'D2']
]

Что я хочу:

const res = {
  A: 'A1',
  B: null,
  C: null,
  D: 'D2'
}

Итак, я хочу объект с уникальным ключом, где, если есть дублированные ключи (например, A, B, C) с различными значениями, значение ключа является ненулевым значением.

Для получения res я могу сделать:

const res = Object.fromEntries(flatten(es))

Но в этом случае res - это:

res = {
    A: null,
    B: null,
    C: null
  }

Я думаю, потому что Object.fromEntries "делает set", а второй A ключ заменяет первый.
Итак, Какой лучший способ сделать то, что я хочу?

Ответы [ 5 ]

2 голосов
/ 27 января 2020

Использование Array.reduce ()

const es = [
  ['A', 'A1'],
  ['B', null],
  ['C', null],
  ['A', null],
  ['B', null],
  ['C', null],
  ['D', 'D2']
]

const reduced = es.reduce((accumulator, currentItem) => {
  const [key, value] = currentItem
  accumulator[key] = accumulator[key] || value
  return accumulator
}, {})

console.log(reduced)
2 голосов
/ 27 января 2020

Вы можете попробовать что-то вроде этого:

Вам нужно установить новое значение, только если:

  • значение пусто null или undefined
  • Оба значения существуют и действительны

Идея состоит в том, чтобы присвоить первое значение и заменить его последним непустым значением.

const es = [
  ['A', 'A1'], // first A key
  ['B', null],
  ['C', null],
  ['A', null], // second A key
  ['B', null],
  ['C', null],
  ['D', 'D2']
]

const result = es.reduce((acc, [ key, value ]) => {  
  if (acc[ key ] == null || !!acc[ key ] && !!value) acc[key] = value;
  return acc
}, {});

console.log(result)
1 голос
/ 27 января 2020

Я бы просто использовал al oop, проверяя, есть ли у объекта свойство или нет, но оно имеет значение null:

const obj = {};
for (const [key, value] of es) {
    if (!(key in obj) || obj[key] === null) {
        obj[key] = value;
    }
}

Live Пример:

const es = [
  ['A', 'A1'], // first A key
  ['B', null],
  ['C', null],
  ['A', null], // second A key
  ['B', null],
  ['C', null],
  ['D', 'D2']
];
const obj = {};
for (const [key, value] of es) {
    if (!(key in obj) || obj[key] === null) {
        obj[key] = value;
    }
}
console.log(obj);

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

0 голосов
/ 27 января 2020

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

var es =[
  ['A', 'A1'], // first A key
  ['B', null],
  ['C', null],
  ['A', null], // second A key
  ['B', null],
  ['C', null],
  ['D', 'D2']
]
var obj={};
var dist = [...new Set(es.map(function(x){
if(!obj[x[0]])
obj[x[0]] = x[1];
return obj;
}))][0]
console.log(dist);
0 голосов
/ 27 января 2020

Вы можете использовать простой forEach l oop для перебора внутренних массивов и обновления существующих свойств объекта, если они все еще null, но есть новое значение:

const es = [
  ['A', 'A1'], // first A key
  ['B', null],
  ['C', null],
  ['A', null], // second A key
  ['B', null],
  ['C', null],
  ['D', 'D2']
]

let obj = {};
es.forEach(arr => {
  // check if object key does not exist yet; or has null value and can be updated with non-null value
  if (!obj.hasOwnProperty(arr[0]) || (obj[arr[0]] === null && arr[1] !== null)) {
    obj[arr[0]] = arr[1];
  }
});
console.info(obj);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...