【问题标题】:jQuery compare key of one array with value of another array and return matchjQuery将一个数组的键与另一个数组的值进行比较并返回匹配
【发布时间】:2017-05-19 19:09:01
【问题描述】:

使用 $.getJSON 从外部 .json 文件中获取数据,内容如下。

{
    "title_12345":"<span class=\"header-class\">Header</span>",
    "p_12345":"<span class=\"description-class\">description</span>",
    "p_23456":"Another paragraph",
    "p_34567":"Another second paragraph",
    "desc": [
        "title_12345", 
        "p_12345",  
        {
            "ul_12345": [
                "li_1", 
                "li_2"
            ]
        },
        "p_23456",  
        {
            "ul_12345": [
                "li_3",
                {
                  "ul_23456": [
                    "li_6",
                    "li_7"
                  ]
                }, 
                "li_4",
                "li_5"
            ]
        }
    ],
    "li_1":"Listing One",
    "li_2":"Listing Two",
    "li_3":"Another Listing",
    "li_4":"Another Second Listing",
    "li_5":"Another Thrid Listing",
    "li_6":"Sub One Listing",
    "li_7":"Sub Two Listing"
}

我想要实现的目标如下。 基于“desc”数组创建一个具有匹配键值对的新对象。

"desc": [
    "title_12345":"<span class=\"header-class\">Header</span>", 
    "p_12345":"<span class=\"description-class\">Description</span>",  
    {
        "ul_12345": [
            "li_1":"Listing One",
            "li_2":"Listing Two"
        ]
    },
    "p_23456":"Another paragraph",  
    {
        "ul_23456": [
            "li_3":"Another Listing",
            {
              "ul_23456": [
                "li_6":"Sub One Listing",
                "li_7":"Sub Two Listing"
              ]
            },
            "li_4":"Another Second Listing"
            "li_5":"Another Thrid Listing"
        ]
    }
]

使用新的“desc”对象,创建 html 内容以附加到 html 页面。 注意“desc”数组=返回数据的DOM层次结构

如果键包含 "title_" ,则在 &lt;h4&gt; 中打印值(不包括 &lt;span&gt;)。结果:&lt;h4&gt;Header&lt;/h4&gt;

如果键包含“p_”,则在&lt;p&gt; 中打印值(不包括&lt;span&gt;)。结果:&lt;p&gt;Description&lt;/p&gt;

如果键包含“ul_”,则在&lt;li&gt; 循环中打印每个对象。结果:&lt;ul&gt;&lt;li&gt;Listing One&lt;/li&gt;&lt;li&gt;Listing Two&lt;/li&gt;&lt;/ul&gt;

这将是附加在页面上的最终结果

<h4>Header</h4>
<p>Description</p>
<ul>
    <li>Listing One</li>
    <li>Listing Two</li>
</ul>
<p>Another paragraph</p>
<ul>
    <li>Another Listing</li>
        <ul>
           <li>Sub One Listing</li> 
           <li>Sub Two Listing</li>
        </ul>
    <li>Another Second Listing</li>
</ul>

知道如何使用 jQuery 实现这个结果吗?提前致谢。

【问题讨论】:

  • “我想要实现的是将“desc”数组值与数据对键值相匹配,如下所示......” - 我想注意你显示的内容此语句下方的 JSON 无效。数组不能有属性。只有对象可以。为了得到你想要的,你需要将desc 转换为一个对象,然后将两个内部对象嵌套在一个额外的数组中......

标签: jquery arrays json object


【解决方案1】:

您可以从您的 JSON 数据中取出 desc 数组,然后像下面这样遍历它-

var temp = YOURJSONDATA;
var desc = temp.desc;
var results = {};
var htmlString = '';
$.each(desc, function(index, item) {
    if(typeof item === 'object') {
      Object.keys(item).forEach(function(key) {
          htmlString += '<ul>';
                $.each(item[key], function(innerIndex, innerItem) {
            if(!results.hasOwnProperty(key)) results[key] = Array();
            results[key][innerItem] = temp.hasOwnProperty(innerItem) ? temp[innerItem] : '';
            console.log(results[key][innerItem]);
            htmlString += getHtmlForKey(innerItem, results[key][innerItem]);
          });
          htmlString +='</ul>';
            });
    } else {
        results[item] = temp.hasOwnProperty(item) ? temp[item] : '';
        htmlString += getHtmlForKey(item, results[item]);
    }
});
function getHtmlForKey(key, value) {
    if(key.indexOf('title_') !== -1) { return "<h4>"+getData(value)+"</h4>"; }
    if(key.indexOf('p_') !== -1) { return "<p>"+getData(value)+"</p>"; }
    if(key.indexOf('li_') !== -1) { return "<li>"+getData(value)+"</li>"; }
}
function getData(str) {
    var testElement= document.createElement('testElement');
    testElement.innerHTML= str;
    return testElement.textContent || testElement.innerText;
} 
//htmlString variable now contains the final HTML string.

请注意,$(value).text() 函数有助于去除 HTML 标签,因此在您只需要没有 html 标签的文本的地方使用它。

这是一个实际操作的小提琴 - https://jsfiddle.net/schikara/0kf7ht3w/8/

【讨论】:

  • 非常感谢您的努力。我无法更改外部 json 格式。必须保留“desc”数组。并且需要根据“desc”数组层次结构在html上打印结果。更新 jsfiddle.net/0kf7ht3w/1 ,注意“p_23456”没有呈现任何值。是不是因为 htmlString 是打印标题、描述、列表的格式?
  • 像魅力一样工作!非常感谢@Shekhar
  • @Shekhar 你能否建议在 li 中是否有另一个子列表。示例 jsfiddle.net/0kf7ht3w/12 -> 在控制台日志 TypeError 上出现错误:key.indexOf 不是函数。 (在'key.indexOf('title_')'中,'key.indexOf'未定义)
  • @ Shekhar ,我现在可以运行它jsfiddle.net/0kf7ht3w/15 -> 如果有办法改进它,请告诉我。谢谢
【解决方案2】:

要实现您的要求,您必须首先根据您的要求解析 JSON,然后从主数据的 span 中提取文本内容。最后,您应该将其附加到某个变量中并使其在您的页面中可见。 Beloa 是示例实施

在这里,我们根据 desc 数组中的值获取 JSON 并从主要内容中提取数据。我们将 li 数据附加到 list 变量中,其余内容将放在 html 变量中。

$.getJSON("test.json", function(result){
    var arr = result.desc;
    var html="",list="<ul>";
    for(var i=0;i<arr.length;i++){                  
        if(typeof(arr[i])=='object'){
            for (var key in arr[i]){
                if(key.indexOf("ul_")!=-1){
                    var liItems = arr[i][key];
                    for(var j=0;j<liItems.length;j++){
                        list+="<li>"+extractText(result[liItems[j]])+"</li>";
                    }
                }
            }
        }
        else if(arr[i].indexOf("title_")!=-1){
            html+="<h4>"+extractText(result[arr[i]])+"</h4>";
        }
        else if(arr[i].indexOf("p_")!=-1){
            html+="<p>"+extractText(result[arr[i]])+"</p>";
        }
    }
    list+="</ul>"
    html+=list;
    $("#showHtml").html(html); // show final html whereever you want.

});

我创建了以下用于从跨度中提取文本内容的函数:

function extractText(s) {
    var span= document.createElement('span');
    span.innerHTML= s;
    return span.textContent || span.innerText;
};

【讨论】:

  • 感谢您的回答。另一个要求是 html 的返回结果需要遵循“desc”数组中定义的层次结构。我更新了我原来的问题。请看一下:)
【解决方案3】:

试试

// Helper function to check if variable is an object(i,e.. {})
function isObject(obj) {
    return Object.prototype.toString.call(obj) === '[object Object]'
}

// Parent for append elements
var parent = $("#parent")

// JSON data
var json = {
    "title_12345": "<span class=\"header-class\">Header</span>",
    "p_12345": "<span class=\"description-class\">Description</span>",
    "p_23456": "Another paragraph",
    "desc": [
        "title_12345",
        "p_12345",
        {
            "ul_12345": [
                "li_1",
                "li_2",
            ]
        },
        "p_23456",
        {
            "ul_131233": [
                "li_21",
                "li_22",
            ]
        }

    ],
    "li_1": "Listing One",
    "li_2": "Listing Two",
    "li_21": "Another Listing",
    "li_22": "Another second paragraph",
}

// Mapping of html tags to be used
var htmltags = {
    'title': 'h4',
    'p': 'p',
    'ul': 'ul',
    'li': 'li'
}

// Iterating over desc, maintains level
json["desc"].forEach(function (element) {

    // Calls approprite method to handle given element
    if (Array.isArray(element)) {
        parseArray(element)
    } else if (isObject(element)) {
        parseObject(element)
    } else {
        var child = document.createElement(htmltags[element.split('_')[0]])
        child.innerHTML = $(json[element]).text() || json[element] || ""
        parent.append(child)
    }
})

function parseArray(element) {
    element.forEach(function (item) {
        if (Array.isArray(item)) {
            parseArray(item)
        } else if (isObject(item)) {
            parseObject(item)
        } else {
            var child = document.createElement(htmltags[item.split('_')[0]])
            child.innerHTML = $(json[item]).text() || json[item] || ""
            parent.append(child)
        }
    })

}

function parseObject(element) {
    Object.keys(element).forEach(function (key) {
        if (Array.isArray(element[key])) {
            var child = document.createElement(htmltags[key.split('_')[0]])
            parent.append(child)
            parent = child
            parseArray(element[key])
            parent = $("#parent")

        } else if (isObject(element[key])) {
            parseObject(element[key])
        } else {
            var child = document.createElement(htmltags[element[key].split('_')[0]])
            child.innerHTML = $(json[element[key]]).text() || ""
            parent.append(child)

        }
    })
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent"></div>

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-01-27
  • 1970-01-01
  • 2022-06-27
  • 2016-08-06
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 2014-07-27
相关资源
最近更新 更多