具有非空值的唯一键

3

我有一个像这样的数组:

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

what I want is:

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

我想要一个带有唯一键的对象,如果存在重复的键(比如ABC)但值不同,则键的值为非空值。

要获得res,可以执行以下操作:

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

但在这种情况下,res 是:

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

我认为是因为 Object.fromEntries "创建了一个set" 并且第二个 A 键替换了第一个键。
那么,有什么最好的方法来实现我想要的效果呢?


什么是“flatten”? - T.J. Crowder
4
如果存在重复的键,而且两个值都不为 null,应该选择第一个、最后一个还是不可能发生重复? - CertainPerformance
5个回答

2
你可以尝试这样做:
只有在以下情况下才需要设置新值:
- 值为空 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)


2
使用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)


1
我会使用循环来检查对象是否没有该属性,或者有该属性但值为null
const obj = {};
for (const [key, value] of es) {
    if (!(key in obj) || obj[key] === null) {
        obj[key] = value;
    }
}

实时示例:

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);

关于 CertainPerformance的问题, 上述代码只获取第一个选项,如果你想要其他选项,需要相应地进行调整。


0
你可以使用一个简单的 forEach 循环来遍历内部数组,并在仍然为 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);


0
我认为你应该使用map和set的组合。这是从一个对象数组中获得不重复元素的最简单方法。

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);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接