停止将对象添加到对象数组(如果已存在)

时间:2018-01-19 16:42:10

标签: jquery arrays

只有当对象尚不存在时才尝试将对象推送到数组。

html包含将id和name(Twig)传递给jQuery的数据属性。

<a
    data-id="{{ franchise.franchise_id }}"
    data-name="{{ franchise.franchise_name }}"
    class="btn btn-buy btn-block add-to-list">
    Add to List
</a>

我正在使用点击事件(.add-to-list)来收集数据(id&amp; name)并将其添加到数组(特许经营)以在视图模板中显示为列表。

这是jQuery:

// initialize array and object variables
let franchises = [];
let franchise = {};

// add to list
$(".add-to-list").on('click', function() {

    // store franchise data in variables
    let id = $(this).data("id");
    let name = $(this).data("name");

    // add values to franchise object
    franchise = {
        'id': id,
        'name': name
    };

    // add object to array if first choice
    if (franchises.length === 0) {
        // alert("franchises array is empty");
        franchises.push({ franchise });
        franchise = {};
    } else {
        // loop thru array as index & obj; loop thru obj as key & value
        // to check if franchise name being added already exists in array
        $.each(franchises, (index, obj) => {
            $.each(obj, (key, value) => {
                // console.log('franchise.name: ' + franchise.name);
                // console.log('value.name: ' + value.name);
                // console.log('key: ' + key);
                if (value.name === franchise.name) {
                    // alert("Franchise already selected");
                    franchise = {};
                    return false;
                } else if (value.name != franchise.name) {
                    franchises.push({franchise});
                }
            });
        });
    }

    // empty franchise obj
    franchise = {};

    // display hidden html
    $("#franchise-selections").css('display', 'block');

    // empty content to display only current elements in franchises[]
    $("#choices").empty();

    // loop thru array as index & obj; then loop thru obj as key & value
    $.each(franchises, (index, obj) => {
        $.each(obj, (key, value) => {
            $("#choices").append('<a class="list-group-item" id='+key.id+'> ' + value.name + '<span class="pull-right">&times;</span></a>');
        });
    });

});

当我在数组中添加一个项目时,console.log会显示值匹配,并且警报会验证是否找到了匹配项,但该对象无论如何都会添加到数组中。这让我很难过。

我无法弄清楚它将项目添加到数组的代码有什么问题。

感谢您找到我的错误的任何帮助。

谢谢!

2 个答案:

答案 0 :(得分:0)

以下是解决上述问题的jQuery。

// create array to hold franchise list
let franchises = [];

// add to list
$(".add-to-list").on('click', function() {

    // store franchise data in variables
    let id = $(this).data("id");
    let name = $(this).data("name");

    // add object to empty array (first selection)
    if (franchises.length === 0) {
        franchises.unshift({ 'id': id, 'name': name  });
    } else if (franchises.length > 0) {
        // loop thru array as index & obj to check if new name already in array
        $.each(franchises, (index, obj) => {
            if (obj.name === name) {
                alert("Franchise already selected");
            } else if (obj.name != name) {
                franchises.unshift({ 'id': id, 'name': name  });
            }
        });
    }

    // empty html content to display only current elements in franchises[]
    $("#choices").empty();

    // loop thru array as index & obj
    $.each(franchises, (index, obj) => {
        $("#choices").append('<a class="list-group-item" id='+obj.id+'> ' + obj.name + '<span class="pull-right">&times;</span></a>');
    });
});

答案 1 :(得分:0)

问题是你将在循环的几次迭代中反复推送同一个对象:

franchises.push({franchise});

你只能决定是否应该在循环后添加,因为只有这样你才能确定它还没有出现在数组中。

我留给你解决这个问题,但是我想建议一种更简单的方法来保持列表的唯一性:使用一个按名称键入的对象而不是一个数组:

const franchises = {}; // Not array

$(".add-to-list").on('click', function() {
    // Add values to franchise object
    // If already existing, then this just replaces previous id:
    franchises[$(this).data("name")] = $(this).data("id");
    $("#franchise-selections").css('display', 'block');
    // Empty choices, and populate again by mapping the object to HTML elements
    $("#choices").empty().append(
        $.map(franchises, function(id, name) {
            return $('<a>').addClass("list-group-item").attr('id', id).text(name).append(
                $('<span>').addClass("pull-right").html('&times')
            );
        })
    );
});

现在您不必迭代任何内容来查找您的列表中是否已有名称。你可以简单地分配它。如果已经存在,它将被替换。

我还更新了显示列表的循环,使其更像jQuery。

如果您需要按相反顺序排列项目(最近插入顶部*),请在reverse()后链接map(...)来电,以便最后三行成为:

        }).reverse()
    );
});

(*)所有流行的浏览器在不仅仅是数字时按插入顺序提供对象的属性。如果它们是数字,则以数字顺序排列。但除非你有这样的名字,否则你不会这样。