Put Duplicates under Common Element [closed] - javascript

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have the following code.
<ul id="listOne">
<li class="columnItem>John</li>
<li class="columnItem>James</li>
<li class="columnItem>Mary</li>
</ul>
<ul id="listTwo">
<li class="columnItem>John</li>
<li class="columnItem>Mark</li>
<li class="columnItem>Mary</li>
</ul>
I want to remove the duplicate list items from both list and place it under another list as "CommonList". Something like
<ul id="CommmonList">
<li class="columnItem>John</li>
<li class="columnItem>Mary</li>
</ul>
<ul id="listOne">
<li class="columnItem>James</li>
</ul>
<ul id="listTwo">
<li class="columnItem>Mark</li>
</ul>

You could do this using ES6 Sets.
Here is what you could do.
$(() => {
let names = [];
let nameSet = new Set();
$("li.columnItem").each((idx, ele) => {
nameSet.add($(ele).html())
});
var $common = $("<ul>").addClass("commmonList");
nameSet.forEach((name) => {
if ($("li:contains(" + name + ")").length > 1) {
$("li:contains(" + name + ")").remove();
$("<li>").addClass("columnItem").html(name).appendTo($common);
}
});
$common.appendTo($("div"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul id="listOne">
<li class="columnItem">John</li>
<li class="columnItem">James</li>
<li class="columnItem">Mary</li>
</ul>
<ul id="listTwo">
<li class="columnItem">John</li>
<li class="columnItem">Mark</li>
<li class="columnItem">Mary</li>
</ul>
</div>

Jquery Each function will help you in this problem. You can traverse all list items with a for loop as you see below.
This is the basic solution working in O(n^2), you can use more effective algorithm to compare list elements.
$("#duplicate").on('click',function(){
var CommmonListHtml = "<ul id='CommmonList'>";
$( "#listOne li" ).each(function( index_one ) {
thiz = $(this);
$( "#listTwo li" ).each(function( index ) {
if(thiz.text() == $(this).text()){
CommmonListHtml += "<li>"+$(this).text()+"</li>";
thiz.remove();
$(this).remove();
}
});
});
CommmonListHtml += "</ul>";
$("div.lists").prepend(CommmonListHtml);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='lists'>
<ul id="listOne">
<li class="columnItem">John</li>
<li class="columnItem">James</li>
<li class="columnItem">Mary</li>
</ul>
<ul id="listTwo">
<li class="columnItem">John</li>
<li class="columnItem">Mark</li>
<li class="columnItem">Mary</li>
</ul>
<a href='#' id='duplicate'>Remove Duplicates</a>
</div>

$("#listOne li").each(function(a,c){
$("#listTwo li").each(function(b,d){
if($(c).html()==$(d).html()){
var re=$(c).remove()[0];
$(d).remove();
$("#CommmonList").append(re);
}
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="listOne">
<li class="columnItem">John</li>
<li class="columnItem">James</li>
<li class="columnItem">Mary</li>
</ul>
<ul id="listTwo">
<li class="columnItem">John</li>
<li class="columnItem">Mark</li>
<li class="columnItem">Mary</li>
</ul>
<ul id="CommmonList">
</ul>

Related

JavaScript or jQuery compare two ordered lists using data-attribute

I want to be able to compare two lists using data attribute in either Javascript or jQuery. I can't find an example of this anywhere and don't know how to go about it.
The first list is static and the second list is sortable. Once the user sorts the lists in the right order, [data-compare 1 to 4] in both lists, they click a button to check if they got the matches correct.
There are examples of setting the correct order 1 to X in a single list, but, none I can find to compare two lists.
The basic HTML:
<ul>
<li data-compare="1">Bananas</li>
<li data-compare="2">tomatoes</li>
<li data-compare="3">carrots</li>
<li data-compare="4">dates</li>
</ul>
<ul>
<li data-compare="1">Tree</li>
<li data-compare="4">Palm tree</li>
<li data-compare="2">Bush</li>
<li data-compare="3">In the ground</li>
</ul>
If an ordered list has data-compare attributes with the values 1, 2, 3, 4, you can just check if the the value of the data-compare is identical to the list item's index + 1:
function checkOrdered(list) {
return Array.from(list).every((item, i) => item.getAttribute('data-compare') == (i + 1));
}
console.log(checkOrdered(document.querySelectorAll('#list1 > li')));
console.log(checkOrdered(document.querySelectorAll('#list2 > li')));
<ul id="list1">
<li data-compare="1">Tree</li>
<li data-compare="4">Palm tree</li>
<li data-compare="2">Bush</li>
<li data-compare="3">In the ground</li>
</ul>
<ul id="list2">
<li data-compare="1">Tree</li>
<li data-compare="2">Bush</li>
<li data-compare="3">In the ground</li>
<li data-compare="4">Palm tree</li>
</ul>
You can do the same thing using another list as the compare basis:
function checkOrdered(list1, list2) {
return Array.from(list1).every((item, i) =>
item.getAttribute('data-compare') === list2[i].getAttribute('data-compare'));
}
const src = document.querySelectorAll('#src > li');
const target1 = document.querySelectorAll('#target1 > li');
const target2 = document.querySelectorAll('#target2 > li');
console.log(checkOrdered(src, target1));
console.log(checkOrdered(src, target2));
<ul id="src">
<li data-compare="1">Bananas</li>
<li data-compare="2">tomatoes</li>
<li data-compare="3">carrots</li>
<li data-compare="4">dates</li>
</ul>
<ul id="target1">
<li data-compare="1">Tree</li>
<li data-compare="4">Palm tree</li>
<li data-compare="2">Bush</li>
<li data-compare="3">In the ground</li>
</ul>
<ul id="target2">
<li data-compare="1">Tree</li>
<li data-compare="2">Bush</li>
<li data-compare="3">In the ground</li>
<li data-compare="4">Palm tree</li>
</ul>
You can first get two arrays with data-compare values and then use every method to check if each element is the same in both arrays.
const getData = arr => {
return arr.map(function() {
return $(this).attr('data-compare')
}).get();
}
const l1 = getData($('ul:nth-of-type(1) li'))
const l2 = getData($('ul:nth-of-type(2) li'))
const check = l1.every((e, i) => l2[i] == e);
console.log(check)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li data-compare="1">Bananas</li>
<li data-compare="2">tomatoes</li>
<li data-compare="3">carrots</li>
<li data-compare="4">dates</li>
</ul>
<ul>
<li data-compare="1">Tree</li>
<li data-compare="4">Palm tree</li>
<li data-compare="2">Bush</li>
<li data-compare="3">In the ground</li>
</ul>

How can I select a box which has specific text?

I have this HTML:
<h5>something</h5>
<ul>
<li class="name">John</li>
<li class="age">21</li>
</ul>
<h5>specific text</h5>
<ul>
<li class="name">Peter</li>
<li class="age">19</li>
</ul>
<h5>something else</h5>
<ul>
<li class="name">Ali</li>
<li class="age">62</li>
</ul>
I want to select this part:
<h5>specific text</h5>
<ul>
<li class="name">Peter</li>
<li class="age">19</li>
</ul>
The logic is the content of <h5> tag. I want the one which is specific text. Actually expected result is an array of both that name and that age. Some thing like this: var res = ['Peter', 19];.
But my code selects all those <ul>s:
$('ul').map(function (){
var res = [$(this).find('li.name').text(), $(this).find('li.age').text()];
});
How can I fix it?
You can use :contains() to find the H5 that contains the specific string you want. Then use .next() to get that ul associated with the h5
$("h5:contains('specific text')").next('ul').map(function (){
var res = [$(this).find('li.name').text(), $(this).find('li.age').text()];
console.log(res)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h5>something</h5>
<ul>
<li class="name">John</li>
<li class="age">21</li>
</ul>
<h5>specific text</h5>
<ul>
<li class="name">Peter</li>
<li class="age">19</li>
</ul>
<h5>something else</h5>
<ul>
<li class="name">Ali</li>
<li class="age">62</li>
</ul>
Jquery script for getting data from ul list :
$('ul').map(function (){
var res = [$(this).find('li.name').text(), $(this).find('li.age').text()];
// console.log(res);
});
var htmVal = '';
$('h5').each(function(index){
htmVal = $(this).html();
if(htmVal == 'something else'){
var detail ={name:$(this).next().find('li.name').html(),age:$(this).next().find('li.age').html()};
console.log(detail);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h5>something</h5>
<ul>
<li class="name">John</li>
<li class="age">21</li>
</ul>
<h5>specific text</h5>
<ul>
<li class="name">Peter</li>
<li class="age">19</li>
</ul>
<h5>something else</h5>
<ul>
<li class="name">Ali</li>
<li class="age">62</li>
</ul>

Onclick convert UL to JSON

On my webpage I have an area that summarizes multiple stores. Each store is a list with multiple list items.
<div id="dealersList" class="dealer-summary">
<ul class="dealer-summary-list">
<li class="dealerName">Brecksville</li>
<li class="dealer-summary-listItem">8383 Chippewa Rd.,</li>
<li class="dealer-summary-listItem">Brecksville, Ohio - 44141</li>
<li class="dealer-summary-listItem">(440) 740-0535</li>
</ul>
<ul class="dealer-summary-list">
<li class="dealerName">Dayton</li>
<li class="dealer-summary-listItem">3520 W Siebenthaler Ave.,</li>
<li class="dealer-summary-listItem">Dayton, Ohio - 45406</li>
<li class="dealer-summary-listItem">(937) 567-9578</li>
</ul>
<ul class="dealer-summary-list">
<li class="dealerName">Cleveland</li>
<li class="dealer-summary-listItem">900 Euclid Ave.,</li>
<li class="dealer-summary-listItem">Cleveland, Ohio - 44115</li>
<li class="dealer-summary-listItem">(216) 302-3020</li>
</ul>
<ul class="dealer-summary-list">
<li class="dealerName">Bridgetown</li>
<li class="dealer-summary-listItem">5830 Harrison Ave.,</li>
<li class="dealer-summary-listItem">Cincinnati, Ohio - 45248</li>
<li class="dealer-summary-listItem">(513) 574-2810</li>
</ul>
<ul class="dealer-summary-list">
<li class="dealerName">Columbus</li>
<li class="dealer-summary-listItem">1350 N High St.,</li>
<li class="dealer-summary-listItem">Columbus, Ohio - 43201</li>
<li class="dealer-summary-listItem">(614) 294-2545</li>
</ul>
<ul class="dealer-summary-list">
<li class="dealerName">Toledo</li>
<li class="dealer-summary-listItem">1415 S Byrne Rd.,</li>
<li class="dealer-summary-listItem">Toledo, Ohio - 43614</li>
<li class="dealer-summary-listItem">(419) 382-0792</li>
</ul>
</div>
</div>
I would like to click any List and have it converted to a JSON similar to this
Object
address:"8383 Chippewa Rd.,"
locale:"Brecksville, Ohio - 44141"
phone:"(440) 740-0535"
title:"Brecksville"
I've tried multiple times with incorrect results...
var dealerSummary = [];
$("ul.dealer-summary-list > li").each(function () {
dealerSummary.push({
"title": $(this).text(),
"address": $(this).text(),
"locale": $(this).text(),
"phone":$(this).text()
});
})
Only the clicked item should be converted. Please help.
Assuming your li tags are always in the same order: title, address, locale, phone, you can do this with a simple find() and then concatenate the text of the li into an object.
Here's an example:
$("#dealersList").on("click", "ul", function() {
var obj = {};
var items = $(this).find("li");
obj.title = items.eq(0).text();
obj.address = items.eq(1).text();
obj.locale = items.eq(2).text();
obj.phone = items.eq(3).text();
console.log(obj);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="dealersList" class="dealer-summary">
<ul class="dealer-summary-list">
<li class="dealerName">Brecksville</li>
<li class="dealer-summary-listItem">8383 Chippewa Rd.,</li>
<li class="dealer-summary-listItem">Brecksville, Ohio - 44141</li>
<li class="dealer-summary-listItem">(440) 740-0535</li>
</ul>
<ul class="dealer-summary-list">
<li class="dealerName">Dayton</li>
<li class="dealer-summary-listItem">3520 W Siebenthaler Ave.,</li>
<li class="dealer-summary-listItem">Dayton, Ohio - 45406</li>
<li class="dealer-summary-listItem">(937) 567-9578</li>
</ul>
<ul class="dealer-summary-list">
<li class="dealerName">Cleveland</li>
<li class="dealer-summary-listItem">900 Euclid Ave.,</li>
<li class="dealer-summary-listItem">Cleveland, Ohio - 44115</li>
<li class="dealer-summary-listItem">(216) 302-3020</li>
</ul>
<ul class="dealer-summary-list">
<li class="dealerName">Bridgetown</li>
<li class="dealer-summary-listItem">5830 Harrison Ave.,</li>
<li class="dealer-summary-listItem">Cincinnati, Ohio - 45248</li>
<li class="dealer-summary-listItem">(513) 574-2810</li>
</ul>
<ul class="dealer-summary-list">
<li class="dealerName">Columbus</li>
<li class="dealer-summary-listItem">1350 N High St.,</li>
<li class="dealer-summary-listItem">Columbus, Ohio - 43201</li>
<li class="dealer-summary-listItem">(614) 294-2545</li>
</ul>
<ul class="dealer-summary-list">
<li class="dealerName">Toledo</li>
<li class="dealer-summary-listItem">1415 S Byrne Rd.,</li>
<li class="dealer-summary-listItem">Toledo, Ohio - 43614</li>
<li class="dealer-summary-listItem">(419) 382-0792</li>
</ul>
</div>
You can add event listeners on all the ul and then just create an object with the desired properties assuming li order doesn't change.
var uls = document.querySelectorAll('.dealer-summary-list');
var obj = {};
uls.forEach(function(ul){
ul.addEventListener('click', function(){
var lis = ul.querySelectorAll('li');
obj.address = lis[1].innerText;
obj.locale = lis[2].innerText;
obj.phone = lis[3].innerText;
obj.title = lis[0].innerText;
console.log(JSON.stringify(obj));
});
});

How to get all decendant li of ul even under another ul

how can i get "all" attr("class") of li under ul#div and return it as array with out repeating same value of class?
<ul id="div">
<li class="a"></li>
<li class="aa">
<ul id="set">
<li class="aa1"></li>
<li class="aa2"></li>
</ul>
</li>
<li class="aaa"></li>
<li class="aaa"></li>
<li class="aaa"></li>
<li class="a"></li>
</ul>
im looking for return like this:
return class in array(a,aa,aa1,aa2,aaa)
Get all <li> descendants of <ul> that have a class attribute, make it into a standard array, then get classes of each one.
var classes = $('ul li[class]').toArray().map(function(el) { return el.className });
console.log(classes);
<!-- results pane console output; see http://meta.stackexchange.com/a/242491 -->
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="div">
<li class="a"></li>
<li class="aa">
<ul id="set">
<li class="aa1"></li>
<li class="aa2"></li>
</ul>
</li>
<li class="aaa"></li>
<li class="aaa"></li>
<li class="aaa"></li>
<li class="a"></li>
</ul>
With pure JavaScript, you could do something like this
var node = document.getElementById("div");
var children = node.childNodes;
var output = [];
for (var i = 0; i < children.length; i++)
{
if (typeof children[i].className !== "undefined")
output.push(children[i].className);
}

Convert dynamic DOM structure to JSON

How can convert below DOM to JSON array which will have many more leafs in thefuture . I have tried a lot but didn't got any solution. I found this but it is not possible in my case.
HTML Code
<ul id="org1">
<li>
Main
<ul data-self="1">
<li data-self="2" data-parent="1">A
<ul data-self="2">
<li data-self="5" data-parent="2">A1</li>
<li data-self="6" data-parent="2">A2</li>
<li data-self="7" data-parent="2">A3</li>
<li data-self="8" data-parent="2">A4</li>
<li data-self="9" data-parent="2">A5</li>
<li data-self="10" data-parent="2">A6</li>
</ul>
</li>
<li data-self="3" data-parent="1">B
<ul data-self="3">
<li data-self="11" data-parent="3">B1</li>
<li data-self="12" data-parent="3">B2</li>
<li data-self="13" data-parent="3">B3</li>
<li data-self="14" data-parent="3">B4</li>
</ul>
</li>
</ul>
</li>
</ul>
JSON Required is
{
1:{
2:{5,6,7,8,9,10},
3:{11,12,13,14}
}
}
Script
function recursive(dis)
{
$(this).find(' > ul ').each(function(){
params[$(this).attr('data-self')]=[];
var i=0;
$(this).find('li').each(function(){
if($(this).has('ul'))
{
params[$(this).attr('data-parent')][i++]=rec(this);
}else
{
params[$(this).attr('data-parent')][i++]=$(this).attr('data-self');
}
});
});
}
recursive('#org1');
console.log(params);
I would prefer something like the following. The 2 changes in the HTML you need to make are:
1) Add a class to your ul such as <ul data-self="2" class="nodes">. 2) Add a class to the wrapper ul such as <ul data-self="1" class="parent">.
var json = {};
$("#org1").find("ul.parent").each(function() {
var $this = $(this);
json[$this.data("self")] = {};
var $nodes = $this.find("ul.nodes");
$nodes.each(function() {
var children = $(this).find("li").map(function() {
return $(this).data("self")
}).get();
json[$this.data("self")][$(this).data("self")] = children;
});
});
alert (JSON.stringify(json));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="org1">
<li>
Main
<ul data-self="1" class="parent">
<li data-self="2" data-parent="1">A
<ul data-self="2" class="nodes">
<li data-self="5" data-parent="2">A1</li>
<li data-self="6" data-parent="2">A2</li>
<li data-self="7" data-parent="2">A3</li>
<li data-self="8" data-parent="2">A4</li>
<li data-self="9" data-parent="2">A5</li>
<li data-self="10" data-parent="2">A6</li>
</ul>
</li>
<li data-self="3" data-parent="1">B
<ul data-self="3" class="nodes">
<li data-self="11" data-parent="3">B1</li>
<li data-self="12" data-parent="3">B2</li>
<li data-self="13" data-parent="3">B3</li>
<li data-self="14" data-parent="3">B4</li>
</ul>
</li>
</ul>
</li>
</ul>

Categories

Resources