从数组中获取具有唯一ID的第一个对象,并将其放入新列表中

时间:2019-01-14 11:21:58

标签: javascript arrays javascript-objects

我正在从包含对象数组的json文件中下拉列表,问题是某些对象具有相同的ID,我只想提取具有唯一ID的第一个对象(例如1,然后使用唯一ID 2等。)并将它们放在列表中。也就是说,我只需要一个具有唯一ID的列表。

到目前为止,我已经尝试过:

var distinctId = [];

for (var i = 0; i < data.length; i++) {
            var id = data[i]["id"];
            if (distinctId[id] == undefined) {
                distinctId[id] = [];
            }
            distinctId[id].push(data[i]);
            console.log(data[i]);
        }

json文件如下所示:

[
{
id: 1,
field1: ...,
field2: ...
},
{
id: 1,
field1: ...,
field2: ...
},
{
id: 2,
field1: ...,
field2: ...
},
{
id: 2,
field1: ...,
field2: ...
},
{
id: 3,
field1: ...,
field2: ...
},
{
id: 3,
field1: ...,
field2: ...
},
]

4 个答案:

答案 0 :(得分:2)

如果您只想获取对象的前两个唯一id,则可以通过使用.mapdestructing assignment将数组映射到id的数组来实现。

完成此操作后,您可以使用一个集合从阵列中删除所有重复项。最后,您可以使用.splice来保留数组中前2个唯一的id

const arr = [{id:1,field1:'foo',field2:'bar'},{id:1,field1:'foo',field2:'bar'},{id:2,field1:'foo',field2:'bar'},{id:2,field1:'foo',field2:'bar'},{id:3,field1:'foo',field2:'bar'},{id:3,field1:'foo',field2:'bar'}],

res = [...new Set(arr.map(({id}) => id))].splice(0, 2);
console.log(res);

如果希望有一个唯一的对象数组,则可以使用.reduce创建一个新的数组。本质上,通过将数组中的第一个对象添加到其中,然后检查下一个对象是否具有与该对象相同的id来创建新数组。为此,我们使用.every。如果它确实具有相同的id,则转到下一个对象;如果id不同,则可以将其添加到数组中。然后,当我们查看下一个对象时,我们检查它是否与数组中现在2个对象id中的任何一个匹配,如果不匹配,则可以添加它,依此类推。

const arr = [{id:1,field1:'foo1',field2:'bar1'},{id:1,field1:'foo2',field2:'bar2'},{id:2,field1:'foo3',field2:'bar3'},{id:2,field1:'foo4',field2:'bar4'},{id:3,field1:'foo5',field2:'bar5'},{id:3,field1:'foo6',field2:'bar6'}],

res = arr.splice(1).reduce((acc, elem) => acc.every(({id}) => id != elem.id) ? [...acc, elem] : acc, [arr[0]]);
console.log(res);

答案 1 :(得分:1)

您可以缩小数组,并检查是否存在符合您条件的元素:

your_json_array.reduce((destArray, obj) => {
    if (destArray.findIndex(i => i.id === obj.id) < 0) {
      return destArray.concat(obj);
    } else {
      return destArray;
    }
  }, []);

这将为您提供另一个具有所需数据的数组。

答案 2 :(得分:0)

您可以通过使用类似的方法来实现此目的,但是 可能是执行第二个示例中所做的更好的主意。在第二个示例中,您可以看到它存储了所有个重复ID的列表,第一个示例仅适用于偶数个重复ID的情况。如果有三个对象的id属性设置为值1,则在1变量中仍会得到值array

我的意思是,还有其他方法可以实现此目的,可以在某处使用filter函数,等等。如果您需要更多有关如何使用reduce函数的文档,我建议MDN Docs

最后,在示例3中,它只是删除所有重复项,而使用了更现代的语法和功能,例如destructuring

示例1

var objects = [{id: 1,a:'x'},{id:1,a:'x'},{id:2,a:'x'},{id:3,a:'x'}];
var array = objects.reduce((a, i) => {
  a.indexOf(i.id) == -1 ? a.push(i.id) : a.splice(a.indexOf(i.id), 1);
  return a;
}, []);

console.log(array);

示例2

var objects = [{id: 1,a:'x'},{id:1,a:'x'},{id:2,a:'x'},{id:3,a:'x'}];

var array = objects.reduce((a, i) => {
  objects.filter(e => e.id == i.id).length == 1 ?  a.push(i.id) : null; 
  return a;
}, []);

console.log(array);

示例3

const objects = [{id: 1,a:'x'},{id:1,a:'x'},{id:2,a:'x'},{id:3,a:'x'}];

const removeDuplicates = ([...o]) => o.reduce((a, i) => { 
  a.indexOf(i.id) == -1 ? a.push(i) : null; 
  return a
}, []);

console.log(removeDuplicates(objects));

答案 3 :(得分:0)

1)要从原始数组中删除重复项,可以将filter()与作为this传递到过滤方法的可选参数结合使用。

2)要获得具有唯一ids的数组,可以在上一个结果上使用map()

这在下一个示例中显示:

const input = [
    {id: 1, field1: "f1", field2: "f2"},
    {id: 1, field1: "f1", field2: "f2"},
    {id: 2, field1: "f1", field2: "f2"},
    {id: 2, field1: "f1", field2: "f2"},
    {id: 3, field1: "f1", field2: "f2"},
    {id: 3, field1: "f1", field2: "f2"},
];

// Remove duplicates elements.

let res = input.filter(
    function({id}) {return !this.has(id) && this.add(id)},
    new Set()
);

console.log("No duplicates:", res);

// Get a map with only the IDs.

let ids = res.map(({id}) => id);
console.log("Ids:", ids);