繁体   English   中英

如何在不循环的情况下更新数组内的JS对象值?

[英]How to update JS object value inside an array without looping?

我知道有一个类似的问题已经回答了,但我的不同之处在于我不想找到它,我只是想更新它

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

let data = [
  {
    contact_id: 15,
    use_id: 16,
    name: 'ABC',
    phoneNo: '0092123456789',
    checked: false,
  },
  {
    contact_id: 16,
    use_id: 22,
    name: 'DEF',
    phoneNo: '0092123456788',
    checked: false,
  },
  {
    contact_id: 17,
    use_id: 24,
    name: 'XYZ',
    phoneNo: '0092123456787',
    checked: false,
  }
];

现在考虑到这一点,我有一个名为phoneNo的属性,它保证了唯一的值。

现在我想要的是切换给定数字的checked值。

我尝试过的:

for (let i = 0; i < data.length; i++) {
    if (data[i]['phoneNo'] === item.phoneNo) {
        data[i]['checked'] = !data[i]['checked'];
        break; // to make it a little efficent :-)
    }
}

我编写了这段代码并且它运行良好了一段时间但现在我已经意识到列表越来越大而且这段代码一遍又一遍地重复,这是非常低效的。

我想要的是?

有没有办法,我可以直接切换给定phoneNo的值checked属性的值而不循环每个项目?

另一种选择是改变数据的存储方式。 如果phoneNo是唯一的,您可以使用电话号码作为密钥。

 let data2={ '0092123456789':{ contact_id: 15, use_id: 16, name: 'ABC', checked: false, }, '0092123456788':{ contact_id: 16, use_id: 22, name: 'DEF', checked: false, }, '0092123456787':{ contact_id: 17, use_id: 24, name: 'XYZ', checked: false, }}; myPhoneNo = '0092123456787'; data2[myPhoneNo].checked = true; console.log(data2); 

有没有办法,我可以直接切换给定phoneNo的值检查属性的值而不循环每个项目?

不符合您当前的结构。 但是你可以使用Map而不是(或者除了)数组,然后它是微不足道的:

const entry = mappedData.get(item.phoneNo);
entry.checked = !entry.checked;

如果需要遍历map的值,可以使用其values方法中的迭代器,例如:

for (const entry of mappedData) {
    // ...
}

如果您只有一个地图并且由于某种原因需要获取值数组,则可以使用带扩展表示法的values()

const data = [...mappedData.values()];

这是一个仅使用地图而没有数组并循环遍历地图值的示例:

 // ONE TIME, add and remove entries as needed let mappedData = new Map([ { contact_id: 15, use_id: 16, name: 'ABC', phoneNo: '0092123456789', checked: false, }, { contact_id: 16, use_id: 22, name: 'DEF', phoneNo: '0092123456788', checked: false, }, { contact_id: 17, use_id: 24, name: 'XYZ', phoneNo: '0092123456787', checked: false, } ].map(entry => [entry.phoneNo, entry])); console.log("Before:"); for (const {phoneNo, checked} of mappedData.values()) { console.log(`${phoneNo}: ${checked}`); } // Each time you want to toggle let phoneNo = '0092123456788'; console.log(`Checking ${phoneNo}...`); let entry = mappedData.get(phoneNo); entry.checked = !entry.checked; console.log("After:"); for (const {phoneNo, checked} of mappedData.values()) { console.log(`${phoneNo}: ${checked}`); } 

与搜索数组(访问时间是线性的)不同,对Map的条目的访问时间需要是次线性的(通过使用哈希映射或类似方法实现)。

您可以创建一个对象,其键将是电话号码,值将是将引用数组data的对象的对象

 const obj = {} let data = [ { contact_id: 15, use_id: 16, name: 'ABC', phoneNo: '0092123456789', checked: false, }, { contact_id: 16, use_id: 22, name: 'DEF', phoneNo: '0092123456788', checked: false, }, { contact_id: 17, use_id: 24, name: 'XYZ', phoneNo: '0092123456787', checked: false, } ]; data.forEach(x => { obj[x.phoneNo] = x; }) let given = '0092123456788'; obj[given].checked = !obj[given].checked console.log(data) 

如果您知道对象的索引,那么您可以在1行中更改它。 但是,如果数组更改了对象的索引,则必须循环。

不,您必须知道要在数组中更改的元素的索引,或循环遍历所有项目以找到与您要查找的内容匹配的元素。

你必须迭代数组。 但是你可以通过首先找到匹配的索引来缩短你的循环。 您可以先找到给定phoneNo的对象,然后切换值。 请尝试以下代码:

'''const matchData = data.find(x => x.phoneNo === item.phoneNo)matchData.checked =!matchData.checked'''

非常简单,非常快

var data = [{
    contact_id: 15,
    use_id: 16,
    name: 'ABC',
    phoneNo: '0092123456789',
    checked: false,
  },
  {
    contact_id: 16,
    use_id: 22,
    name: 'DEF',
    phoneNo: '0092123456788',
    checked: false,
  },
  {
    contact_id: 17,
    use_id: 24,
    name: 'XYZ',
    phoneNo: '0092123456787',
    checked: false,
  }],
    result = data.some(function(x){return '0092123456787'==x.phoneNo ? true:false});
    console.log(result);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM