循环遍历多维数组以生成新数据并在节点 js / javascript 中追加新的键值

Posted

技术标签:

【中文标题】循环遍历多维数组以生成新数据并在节点 js / javascript 中追加新的键值【英文标题】:Loop over multidimensional array to generate new data and append new key values in node js / javascript 【发布时间】:2020-05-04 22:27:55 【问题描述】:

我有一个这样的对象数组:

var finalresult = [
    "Date": "Wed Jan 15 2020 00:00:00 GMT+0530 (India Standard Time)",
    "data": [
            "intent": "delivery",
            "result": [
                "heading": "Delivered",
            ]
        ,
        
            "intent": "orders",
            "result": [
                "heading": "What is the order status"
            ]
        ,
        
            "intent": "orders",
            "result": [
                "heading":"Where is my order"
            ]
        
    ]
,
    "Date": "Wed Jan 17 2020 00:00:00 GMT+0530 (India Standard Time)",
    "data": [
            "intent": "feedback",
            "result": [
                "heading": "Hello",
            ]
        ,
        
            "intent": "feedback",
            "result": [
                "heading": "You are good"
            ]
        ,
        
            "intent": "picnic",
            "result": [
                "heading":"Lets go on picnic"
            ]
         ,
        
            "intent": "picnic",
            "result": [
                "heading":"Are you coming for the picnic?"
            ]
         ,
        
            "intent": "order",
            "result": [
                "heading":"When should I pick my order"
            ]
        
    ]
]

这是我期望的最终输出:

[
    "Date": "Wed Jan 15 2020 00:00:00 GMT+0530 (India Standard Time)",
    "keywords" : "delivery,orders",
    "html" : "<h1>Delivered</h1><h1>What is the order status</h1><h1>Where is my order</h1>"
,
    "Date": "Wed Jan 17 2020 00:00:00 GMT+0530 (India Standard Time)",
    "keywords" : "feedback,picnic,order",
    "html" : "<h1>Hello</h1><h1>You are good</h1><h1>Lets go on picnic</h1><h1>Are you coming for the picnic?</h1><h1>When should I pick my order</h1>"
]

这是我迄今为止尝试过的:

    var chatstring = "";
    var final = [];
    keywordset = new Set();
    // console.log(JSON.stringify(finalresult))
    for (i = 0; i < finalresult.length; i++) 
        ////chatarr +="<div class='collapsible'></div>";
        for (j = 0; j < finalresult[i].data.length; j++) 
            //console.log(finalresult[c].data)
            keywordset.add(finalresult[i].data[j].intent);
            // console.log(summary);
            generatehtml(finalresult[j].data)
            nloop++;
            if (nloop == (finalresult.length)) 

               final.push(chatstring)
            
        

        //forEach
    

    function generatehtml(data) 
    return new Promise((resolve, reject) => 
        for (s = 0; s < data.length; s++) 

            for (t = 0; t < data[s].result.length; t++) 
                var response = data[s].result[t].heading;
                  var html = "<div" + response + "</div>";
                  chatstring += html;
            

        

    )

我正在使用一个集合来存储唯一的意图值。我正在使用generatehtml() 函数循环数据并生成html。

预期输出:

"chat": [
    "Date": "Wed Jan 15 2020 00:00:00 GMT+0530 (India Standard Time)",
    "keywords" : "delivery,orders",
    "html" : "<h1>Delivered</h1><h1>What is the order status</h1><h1>Where is my order</h1>"
,
    "Date": "Wed Jan 17 2020 00:00:00 GMT+0530 (India Standard Time)",
    "keywords" : "feedback,picnic,order",
    "html" : "<h1>Hello</h1><h1>You are good</h1><h1>Lets go on picnic</h1><h1>Are you coming for the picnic?</h1><h1>When should I pick my order</h1>"
]

我无法弄清楚如何从生成的数据中生成预期的输出数组。 我该怎么做?

【问题讨论】:

【参考方案1】:

您可以使用.map() 遍历输入数组并将每个对象转换为所需的格式:

const data = [
  "Date":"WedJan15202000:00:00GMT+0530(IndiaStandardTime)",
  "data":["intent":"delivery","result":["heading":"Delivered",],"intent":"orders","result":["heading":"Whatistheorderstatus"],"intent":"orders","result":["heading":"Whereismyorder"]]
  , 
  "Date":"WedJan17202000:00:00GMT+0530(IndiaStandardTime)",
  "data":["intent":"feedback","result":["heading":"Hello",],"intent":"feedback","result":["heading":"Youaregood"],"intent":"picnic","result":["heading":"Letsgoonpicnic"],"intent":"picnic","result":["heading":"Areyoucomingforthepicnic?"],"intent":"order","result":["heading":"WhenshouldIpickmyorder"]]
];

const result = data.map(o => (
  Date: o.Date,
  keywords: [...new Set(o.data.map(( intent ) => intent))],
  html: `<h1>$[].concat(...o.data.map(( result ) => result))
                                  .map(( heading ) => heading)
                                  .join("</h1>")</h1>`
));

console.log(result);

【讨论】:

【参考方案2】:

这是您可能会做的事情。

您可以使用以下代码 sn-p 简化您的 for 循环

finalresult.forEach((val) => 
  const output = ;
  output['Date'] = val.Date;
  const intents = [];
  const htmls = [];
  val.data.forEach((obj) => 
    intents.push(obj.intent);
    htmls.push(`<h1>$obj.result[0].heading</h1>`)
  );
  output.keywords = intents.join(',');
  output.html = htmls.join('');
  result.push(output);
);

var finalresult = [
  "Date": "Wed Jan 15 2020 00:00:00 GMT+0530 (India Standard Time)",
  "data": [
      "intent": "delivery",
      "result": [
        "heading": "Delivered",
      ]
    ,
    
      "intent": "orders",
      "result": [
        "heading": "What is the order status"
      ]
    ,
    
      "intent": "orders",
      "result": [
        "heading": "Where is my order"
      ]
    
  ]
, 
  "Date": "Wed Jan 17 2020 00:00:00 GMT+0530 (India Standard Time)",
  "data": [
      "intent": "feedback",
      "result": [
        "heading": "Hello",
      ]
    ,
    
      "intent": "feedback",
      "result": [
        "heading": "You are good"
      ]
    ,
    
      "intent": "picnic",
      "result": [
        "heading": "Lets go on picnic"
      ]
    ,
    
      "intent": "picnic",
      "result": [
        "heading": "Are you coming for the picnic?"
      ]
    ,
    
      "intent": "order",
      "result": [
        "heading": "When should I pick my order"
      ]
    
  ]
];


const result = [];
finalresult.forEach((val) => 
  const output = ;
  output['Date'] = val.Date;
  const intents = [];
  const htmls = [];
  val.data.forEach((obj) => 
    intents.push(obj.intent);
    htmls.push(`<h1>$obj.result[0].heading</h1>`)
  );
  output.keywords = intents.join(',');
  output.html = htmls.join('');
  result.push(output);
);

console.log(result);

【讨论】:

【参考方案3】:

有很多方法可以做到这一点,其他用户也证明了这一点。

还有一个,使用.map() 迭代您的第一个数组,然后使用.reduce() 使用keywordshtml 构建对象,然后将destructed 放入您的初始数组。

我还在每个步骤中包含了 cmets,以便您更轻松。

finalresult.map(result => ( // this will be our final object
  Date: result.Date,
  ...result.data.reduce((accumulator, current) =>  // looping through our data
    if (!accumulator.keywords.includes(current.intent))  // if intent not already in our keywords
       if (accumulator.keywords.length) accumulator.keywords += ','; // if keywords has at least one, add `,`
       accumulator.keywords += current.intent; // add our new keyword
    

    /** on the next line we map result in case 
     *  array has more than 1 object. We build the 
     *  string we need and while map will return 
     *  an array we use join (with empty string as separator) 
     *  to create a string from our array
     **/
    accumulator.html += current.result.map(res => `<h1>$res.heading</h1>`).join(''); 

    return accumulator;
  ,  // our initial object, that will be filled be reduce and the destructed into our upper object
    keywords: "",
    html: ""
  
)
))

编辑:查看 OP 的 cmets 后,由于可能会获得不同的密钥而不是 heading,因此构建正确输出的函数/解析器会更干净。

接下来还会覆盖同一个对象下的多个key。

function myhtmlparser (res) 
  const html = [];

  Object.keys(res).forEach(key => 
    switch (key) 
      case 'heading':
        html.push(`<h1>$res[key]</h1>`);
        break;
      case 'paragraph':
        html.push(`<p>$res[key]</p>`);
        break;
    
  )

  return html.join('');

然后在你的accumulator.html += ...上使用它:

accumulator.html += current.result.map(res => myhtmlparser(res)).join(''); 

【讨论】:

如果数据数组中多次出现相同意图,则此解决方案将跳过 html 值。例如,它认为 html 仅用于意图顺序的一次出现 请帮我解决这个问题。您的解决方案正在运行 它给了我 "Date": "Wed Jan 15 2020 00:00:00 GMT+0530 (India Standard Time)", "keywords" : "delivery,orders", "html" : "

Delivered

What is the order status

" 而不是 "Date": "Wed Jan 15 2020 00:00:00 GMT+0530 (India Standard Time)", "keywords" : "delivery,orders", "html" : "

Delivered

订单状态是什么

我的订单在哪里

"
而不是 res => &lt;h1&gt;$res.heading&lt;/h1&gt;).join('') 你能告诉我一种方法,以便我可以将数据传递给 generatehtml 函数,然后将该值包含在 accumulator.html 中吗? 因为我的标题也可以是这样的:'[\"type\": \"head\", \"text\": \"This is a heading\",\" type\": \"paragraph\", \"text\": \"This is a para\"]' 我将在 generatehtml 函数中解析并返回 html

以上是关于循环遍历多维数组以生成新数据并在节点 js / javascript 中追加新的键值的主要内容,如果未能解决你的问题,请参考以下文章

带有嵌套for循环的Javascript多维数组-无法正常工作

求教一个JQ 遍历 生成多维数组的问题

SystemVerilog foreach 语法,用于循环遍历多维数组的低维

jQuery循环遍历多维数组并显示每个父数组的子数组

通过JS中的数组循环并在引导程序中为HTML feed生成帖子?

循环遍历两个对象数组以将匹配值推送到新数组在 React 中不起作用,但在 JS Fiddle 中起作用