简体   繁体   English

JavaScript 高级减少 function 我无法理解{}[迭代]

[英]JavaScript advanced reduce function I can't get my head around {}[iteration]

I just can't understand this concept in the function below:我只是在下面的 function 中无法理解这个概念:

acc[line[0]]

I really can't get my head around that piece of code, how come it is not be an error and works perfectly?我真的无法理解那段代码,为什么它不是错误并且可以完美运行? How do you interpret it in English words?你如何用英语单词解释它? In my head it is an empty object acc {} at its first iteration and according to the piece of code is trying to access the iterated line at its first value [0].在我的脑海中,它在第一次迭代时是一个空的 object acc {} ,并且根据这段代码正在尝试以其第一个值 [0] 访问迭代行。 How come it works without the need of inverted commas as well?它如何在不需要引号的情况下也能工作? And how does line[0] ended up to be the values of the object? line[0]最终是如何成为 object 的值的?

Here is the full code:这是完整的代码:

let output = [["mark johansson", "waffle iron", "80", "2"], 
 ["mark johansson", "blender", "200", "1"],
 ["mark johansson", "knife", "10", "4"],
 ["Nikita Smith", "waffle iron", "80", "1"],
 ["Nikita Smith", "knife", "10", "2"],
 ["Nikita Smith", "pot", "20", "3"]]

let result =output.reduce((acc,line)=>{
            acc[line[0]] = acc[line[0]] || []
            acc[line[0]].push({
            name: line[1],
            price: line[2],
            quant: line[3]
            })
           return acc
},{})

console.log(JSON.stringify(result,null,1))

{
 "mark johansson": [
  {
   "name": "waffle iron",
   "price": "80",
   "quant": "2"
  },
  {
   "name": "blender",
   "price": "200",
   "quant": "1"
  },
  {
   "name": "knife",
   "price": "10",
   "quant": "4"
  }
 ],
 "Nikita Smith": [
  {
   "name": "waffle iron",
   "price": "80",
   "quant": "1"
  },
  {
   "name": "knife",
   "price": "10",
   "quant": "2"
  },
  {
   "name": "pot",
   "price": "20",
   "quant": "3"
  }
 ]
}

  

Maybe if we replace all the dynamic references with hard-coded values from the first array - or line - in output , it will be clearer as to what is going on.也许如果我们用output中第一个数组或line中的硬编码值替换所有动态引用,就会更清楚发生了什么。 This is essentially what the very first iteration of the reducer function is doing:这基本上是减速器 function 的第一次迭代正在做的事情:

output.reduce((acc, ["mark johansson", "waffle iron", "80", "2"])=>{
    acc["mark johansson"] = acc["mark johansson"] || [];
    acc["mark johansson"].push({
        name: "waffle iron",
        price: "80",
        quant: "2"
    });
    return acc
},{})

Imagine that the first line of the reducer function just said acc["mark johansson"] = acc["mark johansson"] .想象一下,reducer function 的第一行刚刚说acc["mark johansson"] = acc["mark johansson"] Since there is no key on the object acc with the name "mark johansson" , after evaluating that expression the object acc would look like:由于 object acc上没有名为"mark johansson"的键,因此在评估该表达式后, object acc将如下所示:

acc = {
    "mark johansson": undefined
}

However, by adding || []但是,通过添加|| [] || [] onto the end of the expression, we can evaluate whether acc["mark johansson"] is truthy before we actually set the key/value pair. || []添加到表达式的末尾,我们可以在实际设置键/值对之前评估acc["mark johansson"]是否为真。 Since undefined is falsy, the ||由于undefined是假的, || operater kicks in and we get this instead:操作员开始工作,我们得到了这个:

acc = {
    "mark johansson": []
}

Do you see the difference?你看得到差别吗? With the OR operator we are saying: "either acc["mark johansson"] exists and is therefore truthy, and we set it as itself, OR it is falsy and we set it as a blank array".使用 OR 运算符,我们说:“要么acc["mark johansson"]存在,因此为真,我们将其设置为自身,或者它是假的,我们将其设置为空白数组”。 The rest of the code should be fairly self explanatory.代码的 rest 应该是相当不言自明的。 The key/value pair is now guaranteed to exist and we can push the data object to the array.现在保证键/值对存在,我们可以将数据 object 推送到数组中。 Any further lines which reference acc["mark johansson"] will target the already existing entry.任何其他引用acc["mark johansson"]的行都将针对已经存在的条目。

It helps if you console log after each step to see what is going on:如果您在每个步骤之后控制台日志以查看发生了什么,这会有所帮助:

 let output = [ ["mark johansson", "waffle iron", "80", "2"], ["mark johansson", "blender", "200", "1"], ["mark johansson", "knife", "10", "4"], ["Nikita Smith", "waffle iron", "80", "1"], ["Nikita Smith", "knife", "10", "2"], ["Nikita Smith", "pot", "20", "3"] ] let result = output.reduce((acc, line) => { console.log("acc value at start:", acc, "current line value:", line) acc[line[0]] = acc[line[0]] || [] //either a new key will appear with an empty array as the value, or the acc will appear unchanged console.log("acc value after key configuration:", acc) acc[line[0]].push({ name: line[1], price: line[2], quant: line[3] }) //there will be one new object within one of the keys' array value; //acc will appear the same in the first console log of the next cycle console.log("acc after current line values pushed as new object:", acc) return acc }, {}) console.log(JSON.stringify(result))
The code snippet above has notes detailing what to look for in the console logs, below is the actual line by line explaination: 上面的代码片段详细说明了在控制台日志中要查找的内容,下面是实际的逐行解释:

 //pass {} as the initial value (acc) and cycle through each inner array within output array as current value(line) let result = output.reduce((acc,line)=>{ //if line[0], which is the name in each inner array, already exists as a key //then equate key to equal its current value as to not overwrite //otherwise equate key to equal a new empty array //basically, whenever line[0] value changes to another name, a new key will be created acc[line[0]] = acc[line[0]] || [] //now push the other values of the current inner array //into the key which matches that inner arrays first value(which is the name) acc[line[0]].push({ name: line[1], price: line[2], quant: line[3] }) //pass the object to the next cycle return acc },{})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM