在推送到阵列之前搜索多维数组,没有重复数据

时间:2016-06-17 10:40:01

标签: javascript jquery arrays local-storage

我正在尝试构建'wishlist'功能。单击按钮时,它会保存本地存储中阵列中特定“属性”的名称和链接。然后,我将在页面上为用户输出。

到目前为止它的工作原理,我唯一的问题是它将始终插入属性名称和链接,即使它已经存在于数组中。我需要创建一个检查,看看它是否已经存在,只有在无法找到它时才推送它。

这是一个可行的JSFiddle。单击“保存”按钮并检查localStorage,您将看到添加了数据。但是再次点击同一个按钮,你会再次看到它被添加。

https://jsfiddle.net/g9kkx3fh/3/

这是基本代码。它从最近点击的按钮抓取属性名称和链接,它从localStorage中的数组中提取数据,然后使用.push添加新数据,然后重新串行它并将其添加回localStorage。

var name = $(this).closest('.text-long').find('.intro-text h4').text();
var permalink = $(this).closest('.text-long').find('.button-slot a').attr('href');
var property = [name, permalink]; // create an array of the name + permalink
var wishlist = JSON.parse(localStorage.getItem("wishlist")); // get the wishlist from storage
wishlist.push(property); // append the new array into the wishlist from storage
localStorage.setItem('wishlist', JSON.stringify(wishlist)); // put the wishlist back in storage

我知道我需要迭代数组,是多维的,并寻找相同的name var。所以我从这开始:

for (var i = 0; i < wishlist.length; i++) {
    var isPresent = ($.inArray(name, wishlist[i]));
}
if (isPresent == -1){
    wishlist.push(property);
    localStorage.setItem('wishlist', JSON.stringify(property));
}

这是问题所在。如果localStorage var wishlist为空,则其length为0.因此for循环永远不会起作用,因为i < wishlist.length永远不会为真,因为wishlist是总是0。

那么我该如何解决这个问题呢?我永远无法向数组中添加任何内容,因为我永远无法获得isPresent的值,因为我的for循环永远不会有效。

这是一个破坏代码的JSFiddle,但是添加了for循环和if语句:

https://jsfiddle.net/bdxa0sgz/1/

我也尝试了以下内容:

if (isPresent == -1 || wishlist.length == 0){
...
}

因此,如果心愿单是空的,它仍然会运行。然而,这似乎混杂了name数据并覆盖了数组。我很困惑。

https://jsfiddle.net/bdxa0sgz/5/

2 个答案:

答案 0 :(得分:0)

使用Map(键,值)对来存储您的属性,以便您可以使用

进行检查
myMap.get(key)

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get

在这里,请看一下这篇详细的文章:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map

对于您的示例,

var myMap = new Map();
$('body').on('click', '.icon.heart button', function(e) {
    var name = $(this).closest('.text-long').find('.intro-text h4').text();
    var permalink = $(this).closest('.text-long').find('.button-slot a').attr('href');
    var property = [name, permalink];
    console.log(property);
    if (myMap.get(name) === null) {
        var wishlist = JSON.parse(localStorage.getItem("wishlist"));
        console.log('Wishlist from localStorage = ' + wishlist);
        wishlist.push(property);
        console.log(wishlist);
        localStorage.setItem('wishlist', JSON.stringify(wishlist));
        myMap.set(name, permalink);
    }
});

您还可以遍历地图以获取所有这些属性:

var mapIter = myMap[Symbol.iterator]();
console.log(mapIter.next().value); 

我希望这适合你。

答案 1 :(得分:0)

在将property数组推送到wishlist数组之前,您必须检查wishlist是否包含它。所以你可能会这样做。让我们发明一个通用的Array.prototype.compare()方法。但是,由于这将是一种通用方法,因此它还会处理数组元素作为对象的可能性。所以我们也有一个Object.prototype.compare()(在这种情况下我们不需要它,但很高兴知道)所以这里是代码;

Object.prototype.compare = function(o){
  var ok = Object.keys(this);
  return typeof o === "object" && ok.length === Object.keys(o).length ? ok.every(k => this[k] === o[k]) : false;
};
Array.prototype.compare = function(a){
  return this.every((e,i) => typeof a[i] === "object" ? a[i].compare(e) : a[i] === e);
};
var button1 = ["29 Melton Road32 York Road","http://localhost:8888/test-properties/properties/29-melton-road/"],
    button2 = ["32 York Road","http://localhost:8888/test-properties/properties/32-york-road/"],
   wishlist = [],
    push2wl = btn => wishlist.some(a => a.compare(btn)) ? wishlist : wishlist.concat([btn]); // if exists return wishlist untouched
wishlist = push2wl(button1); 
wishlist = push2wl(button2); 
wishlist = push2wl(button1); // this won't get inserted
wishlist = push2wl(button2); // this won't get inserted

console.log(wishlist);

我使用箭头功能,但如果您希望在Safari 9或IE上看到您的代码正常工作,则可以将它们替换为传统功能。