如何索引对象属性?

How can I index object properties?

我有一个包含人名和服务时间的对象列表。这些名称在此列表中可能出现不止一次,并且每次出现的服务时间可能不同。我想要做的是创建一个名称的 HashSet,并附加一个索引,这样我就可以将它引用回更大的列表,而不必创建嵌套的 for 循环。例如,如果我有列表:

[{Name: 'john doe', ServiceTime: '20min'}, {Name: 'john doe', ServiceTime: '25min'},
 {Name: 'john doe', ServiceTime: '31min'}, {Name: 'billy bob', ServiceTime: '1min'},
 {Name: 'billy bob', ServiceTime: '12min'}, {Name: 'john doe', ServiceTime: '19min'}]

我创建的 HashSet 如下所示:

{'john doe': 0, 'billy bob': 1}

这是我的做法:

let count = 0;
 list.map(obj => arr[obj.Name] = arr[obj.Name] ? arr[obj.Name] : count++)

每次发现一个新人时,密钥的值都会递增,如果这有意义的话。完成后,我遍历我创建的新名称对象,创建一个对象数组,它将保存人员姓名和一个数组来保存他们的服务时间,如下所示:

[{Name: 'john doe', ServiceTimes:[]}, {Name: 'billy bob', ServiceTimes:[]}]

有了这些信息,我可以返回并遍历我的初始列表,更新索引以通过我的 HashSet 的键值对进行搜索,如下所示:

list.map(obj => { 
            let index = arr[obj.Name];

            if(temp[index] !== undefined){
                temp[index].ServiceTimes.push(obj)
            }
        })

我面临的问题是,在创建我的 HashSet 之后,我注意到我的索引出现了 1 个错误。例如,我上面提供的列表给了我 HashSet:

{'john doe': 1, 'billy bob': 2}

和其他列表我得到了 HashSet

{'john doe': 0, 'billy bob': 1}

我显然希望我的 HashSet 看起来像最后一个,但似乎无法理解为什么我的计数在某些情况下被添加两次而在其他情况下却没有。如果有人能指出我正确的方向或理解我可能做错了什么导致这个问题,我将不胜感激。谢谢!

P.S。抱歉问题太长了。

let count = 0;
list.map(obj => arr[obj.Name] = arr[obj.Name] ? arr[obj.Name] : count++)

您永远不会重置 count 变量。您应该在找到新人名时重置计数变量。

let data = [
  {Name: 'john doe', ServiceTime: '20min'}, 
  {Name: 'john doe', ServiceTime: '25min'},
 {Name: 'john doe', ServiceTime: '31min'}, 
 {Name: 'billy bob', ServiceTime: '1min'},
 {Name: 'billy bob', ServiceTime: '12min'}, 
 {Name: 'john doe', ServiceTime: '19min'}
];

let final = {};
let found = 0;
data.forEach((obj, index) => {
  if (!final.hasOwnProperty(obj.Name)) {
    final[obj.Name] = found;
    found += 1;

    return;
  }
})

console.log(final);

您可以只使用 reduce() 遍历数组。当你 运行 减速器时,你可以在其中做任何事情。如下图

let data = [
 {Name: 'john doe', ServiceTime: '20min'},
 {Name: 'john doe', ServiceTime: '25min'},
 {Name: 'john doe', ServiceTime: '31min'},
 {Name: 'billy bob', ServiceTime: '1min'},
 {Name: 'billy bob', ServiceTime: '12min'},
 {Name: 'john doe', ServiceTime: '19min'}];

let mappedData = data.reduce((accumulator, currentItem, index) => {
      const {Name, ServiceTime} = currentItem;
      if(!accumulator.hasOwnProperty(Name)) {
        accumulator[Name] = {
          firstMatchedAtindex: index,
          count: 0,
          serviceTimes: []
        };
      }

      accumulator[Name].count += 1 ;
      accumulator[Name].serviceTimes.push({index, ServiceTime});
      return accumulator;
      
}, {})

console.log(mappedData);

更简单的脚本...

let data = [
 {Name: 'john doe', ServiceTime: '20min'},
 {Name: 'john doe', ServiceTime: '25min'},
 {Name: 'john doe', ServiceTime: '31min'},
 {Name: 'billy bob', ServiceTime: '1min'},
 {Name: 'billy bob', ServiceTime: '12min'},
 {Name: 'john doe', ServiceTime: '19min'}];

let mappedData = data.reduce((accumulator, currentItem, index) => {
      const {Name, ServiceTime} = currentItem;
      if(!accumulator.hasOwnProperty(Name)) {
        accumulator[Name] = index;
      }

      return accumulator;
      
}, {})

console.log(mappedData);

另请注意数组 map 回调函数可让您访问索引。例如

const list = [
 {Name: 'john doe', ServiceTime: '20min'},
 {Name: 'john doe', ServiceTime: '25min'},
 {Name: 'john doe', ServiceTime: '31min'},
 {Name: 'billy bob', ServiceTime: '1min'},
 {Name: 'billy bob', ServiceTime: '12min'},
 {Name: 'john doe', ServiceTime: '19min'}];

 const transformed = list.map((obj, index) => { 
   return {
     ...obj,
     index
   }
 });
console.log(transformed);

// Same with forEach alternative to for loop
list.forEach((obj, index) => { 
    console.log(obj, index);
 });